Documentation Index
Fetch the complete documentation index at: https://trigger-docs-mcp-readonly-runtime-flag.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Lightpanda is a purpose-built browser for AI and automation workflows. It is 10x faster, uses 10x less RAM than Chrome headless.
Here are a few examples of how to use Lightpanda with Trigger.dev.
WEB SCRAPING: When web scraping, you MUST use a proxy to comply with our terms of service. Direct scraping of third-party websites without the site owner’s permission using Trigger.dev Cloud is prohibited and will result in account suspension. See this example which uses a proxy.
Limitations
- Lightpanda does not support the
puppeteer screenshot feature.
Using Lightpanda Cloud
Prerequisites
Get links from a website
In this task we use Lightpanda browser to get links from a provided URL. You will have to pass the URL as a payload when triggering the task.
Make sure to add LIGHTPANDA_TOKEN to your Trigger.dev dashboard on the Environment Variables page:
LIGHTPANDA_TOKEN="<your-token>"
trigger/lightpanda-cloud-puppeteer.ts
import { logger, task } from "@trigger.dev/sdk";
import puppeteer from "puppeteer-core";
export const lightpandaCloudPuppeteer = task({
id: "lightpanda-cloud-puppeteer",
machine: {
preset: "micro",
},
run: async (payload: { url: string }, { ctx }) => {
logger.log("Lets get a page's links with Lightpanda!", { payload, ctx });
if (!payload.url) {
logger.warn("Please define the payload url");
throw new Error("payload.url is undefined");
}
const token = process.env.LIGHTPANDA_TOKEN;
if (!token) {
logger.warn("Please define the env variable LIGHTPANDA_TOKEN");
throw new Error("LIGHTPANDA_TOKEN is undefined");
}
// Connect to Lightpanda's cloud
const browser = await puppeteer.connect({
browserWSEndpoint: `wss://cloud.lightpanda.io/ws?browser=lightpanda&token=${token}`,
});
const context = await browser.createBrowserContext();
const page = await context.newPage();
// Dump all the links from the page.
await page.goto(payload.url);
const links = await page.evaluate(() => {
return Array.from(document.querySelectorAll("a")).map((row) => {
return row.getAttribute("href");
});
});
logger.info("Processing done, shutting down…");
await page.close();
await context.close();
await browser.disconnect();
logger.info("✅ Completed");
return {
links,
};
},
});
Proxies
Proxies can be used with your browser via the proxy query string parameter. By default, the proxy used is “datacenter” which is a pool of shared datacenter IPs.
datacenter accepts an optional country query string parameter which is an ISO 3166-1 alpha-2 country code.
# This example will use a German IP
wss://cloud.lightpanda.io/ws?proxy=datacenter&country=de&token=${token}
Session
A session is alive until you close it or the connection is closed. The max duration of a session is 15 minutes.
Using Lightpanda browser directly
Prerequisites
Get the HTML of a webpage
This task will dump the HTML of a provided URL using the Lightpanda browser binary. You will have to pass the URL as a payload when triggering the task.
trigger/lightpanda-fetch.ts
import { logger, task } from "@trigger.dev/sdk";
import { execSync } from "node:child_process";
export const lightpandaFetch = task({
id: "lightpanda-fetch",
machine: {
preset: "micro",
},
run: async (payload: { url: string }, { ctx }) => {
logger.log("Lets get a page's content with Lightpanda!", { payload, ctx });
if (!payload.url) {
logger.warn("Please define the payload url");
throw new Error("payload.url is undefined");
}
const buffer = execSync(`lightpanda fetch --dump ${payload.url}`);
logger.info("✅ Completed");
return {
message: buffer.toString(),
};
},
});
Lightpanda CDP with Puppeteer
This task initializes a Lightpanda CDP server and uses it with puppeteer-core to scrape a provided URL.
trigger/lightpanda-cdp.ts
import { logger, task } from "@trigger.dev/sdk";
import { spawn, type ChildProcessWithoutNullStreams } from "node:child_process";
import puppeteer from "puppeteer-core";
const spawnLightpanda = async (host: string, port: string) =>
new Promise<ChildProcessWithoutNullStreams>((resolve, reject) => {
const child = spawn("lightpanda", [
"serve",
"--host",
host,
"--port",
port,
"--log_level",
"info",
]);
child.on("spawn", async () => {
logger.info("Running Lightpanda's CDP server…", {
pid: child.pid,
});
await new Promise((resolve) => setTimeout(resolve, 250));
resolve(child);
});
child.on("error", (e) => reject(e));
});
export const lightpandaCDP = task({
id: "lightpanda-cdp",
machine: {
preset: "micro",
},
run: async (payload: { url: string }, { ctx }) => {
logger.log("Lets get a page's links with Lightpanda!", { payload, ctx });
if (!payload.url) {
logger.warn("Please define the payload url");
throw new Error("payload.url is undefined");
}
const host = process.env.LIGHTPANDA_CDP_HOST ?? "127.0.0.1";
const port = process.env.LIGHTPANDA_CDP_PORT ?? "9222";
// Launch Lightpanda's CDP server
const lpProcess = await spawnLightpanda(host, port);
const browser = await puppeteer.connect({
browserWSEndpoint: `ws://${host}:${port}`,
});
const context = await browser.createBrowserContext();
const page = await context.newPage();
// Dump all the links from the page.
await page.goto(payload.url);
const links = await page.evaluate(() => {
return Array.from(document.querySelectorAll("a")).map((row) => {
return row.getAttribute("href");
});
});
logger.info("Processing done");
logger.info("Shutting down…");
// Close Puppeteer instance
await browser.close();
// Stop Lightpanda's CDP Server
lpProcess.kill();
logger.info("✅ Completed");
return {
links,
};
},
});