Skip to main content

Prerequisites

Build configuration

Add the Puppeteer build extension to your trigger.config.ts:
trigger.config.ts
import { defineConfig } from "@trigger.dev/sdk";
import { puppeteer } from "@trigger.dev/build/extensions/puppeteer";

export default defineConfig({
  project: "<project ref>",
  build: {
    extensions: [puppeteer()],
  },
});

Set the executable path

Add the following environment variable in your Trigger.dev dashboard:
PUPPETEER_EXECUTABLE_PATH=/usr/bin/google-chrome-stable

Example 1: Log a page title

The simplest Puppeteer task — opens a browser, navigates to a URL, and logs the page title.
trigger/puppeteer-basic-example.ts
import { logger, task } from "@trigger.dev/sdk";
import puppeteer from "puppeteer";

export const puppeteerTask = task({
  id: "puppeteer-log-title",
  run: async () => {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();

    await page.goto("https://trigger.dev");

    const content = await page.title();
    logger.info("Page title", { content });

    await browser.close();
  },
});
No payload is needed. Click Run test on the Test page in the dashboard.

Example 2: Generate a PDF from a web page

This task opens a web page, generates a PDF, and uploads it to Cloudflare R2.
trigger/puppeteer-generate-pdf.ts
import { logger, task } from "@trigger.dev/sdk";
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";
import puppeteer from "puppeteer";

const s3Client = new S3Client({
  region: "auto",
  endpoint: process.env.S3_ENDPOINT,
  credentials: {
    accessKeyId: process.env.R2_ACCESS_KEY_ID ?? "",
    secretAccessKey: process.env.R2_SECRET_ACCESS_KEY ?? "",
  },
});

export const puppeteerWebpageToPDF = task({
  id: "puppeteer-webpage-to-pdf",
  run: async () => {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    const response = await page.goto("https://trigger.dev");
    const url = response?.url() ?? "No URL found";

    const generatePdf = await page.pdf();
    logger.info("PDF generated from URL", { url });

    await browser.close();

    // Upload to R2
    const s3Key = `pdfs/test.pdf`;
    await s3Client.send(
      new PutObjectCommand({
        Bucket: process.env.S3_BUCKET,
        Key: s3Key,
        Body: generatePdf,
        ContentType: "application/pdf",
      })
    );

    const s3Url = `https://${process.env.S3_BUCKET}.s3.amazonaws.com/${s3Key}`;
    logger.log("PDF uploaded to R2", { url: s3Url });

    return { pdfUrl: s3Url };
  },
});
No payload is needed. Click Run test on the Test page in the dashboard.

Example 3: Scrape content from a web page

This task uses Puppeteer with a BrowserBase proxy to scrape the GitHub stars count from the Trigger.dev landing page.
When scraping websites you don’t own on Trigger.dev Cloud, you must use a proxy via browserWSEndpoint. Direct scraping without a proxy is prohibited and may result in account suspension. Screenshots while scraping are also prohibited. Always ensure you have permission from the website owner before scraping.
trigger/scrape-website.ts
import { logger, task } from "@trigger.dev/sdk";
import puppeteer from "puppeteer-core";

export const puppeteerScrapeWithProxy = task({
  id: "puppeteer-scrape-with-proxy",
  run: async () => {
    const browser = await puppeteer.connect({
      browserWSEndpoint: `wss://connect.browserbase.com?apiKey=${process.env.BROWSERBASE_API_KEY}`,
    });

    const page = await browser.newPage();

    try {
      await page.goto("https://trigger.dev", { waitUntil: "networkidle0" });

      const starCount = await page.evaluate(() => {
        const starElement = document.querySelector(".github-star-count");
        const text = starElement?.textContent ?? "0";
        return parseInt(text.replace(/[^0-9]/g, ""));
      });

      logger.info("GitHub star count", { starCount });
      return { starCount };
    } catch (error) {
      logger.error("Error during scraping", {
        error: error instanceof Error ? error.message : String(error),
      });
      throw error;
    } finally {
      await browser.close();
    }
  },
});
No payload is needed. Click Run test on the Test page in the dashboard.

Proxy services

If you are using Trigger.dev Cloud and scraping content from websites you don’t own, use one of these proxy services with browserWSEndpoint:

Local development

When running locally with trigger.dev dev, the Puppeteer build extension is not applied. You need Chrome or Chromium installed locally. Puppeteer will automatically download a compatible Chromium build when you run npm install puppeteer.

Build docs developers (and LLMs) love