Skip to content

Commit 5ea6605

Browse files
nrigaudierenicktrn
andauthored
feat(extensions): add lightpanda (#2192)
* feat: add lightpanda structure * chore: add lightpanda doc links * fix: lightpanda extension instructions * feat: add Lightpanda guide and examples * feat: lightpanda - add 3rd example * feat: add lightpandaTask * fix: lightpanda 3rd example * fix: lightpanda 1st example * chore: add changeset * add v4 tag to guide * fix: merge lightpanda docker instructions * fix: add failsafes * add scrape warning * lint * successful login also switches to that profile * update docs and links as this is v4 only * extension tweaks * simplify extension * update examples * update docs * remove from extensions list as v4 only * remove from catalog * update changeset --------- Co-authored-by: nicktrn <[email protected]>
1 parent 3e1cc69 commit 5ea6605

File tree

16 files changed

+684
-20
lines changed

16 files changed

+684
-20
lines changed

.changeset/empty-dolls-judge.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"trigger.dev": patch
3+
---
4+
5+
Switch to profile after successful login

.changeset/rare-mails-fail.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@trigger.dev/build": patch
3+
---
4+
5+
Add Lightpanda extension

docs/config/extensions/lightpanda.mdx

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
---
2+
title: "Lightpanda"
3+
sidebarTitle: "lightpanda"
4+
description: "Use the lightpanda build extension to add Lightpanda browser to your project"
5+
tag: "v4"
6+
---
7+
8+
import UpgradeToV4Note from "/snippets/upgrade-to-v4-note.mdx";
9+
10+
<UpgradeToV4Note />
11+
12+
To use the Lightpanda browser in your project, add the extension to your `trigger.config.ts` file:
13+
14+
```ts trigger.config.ts
15+
import { defineConfig } from "@trigger.dev/sdk";
16+
import { lightpanda } from "@trigger.dev/build/extensions/lightpanda";
17+
18+
export default defineConfig({
19+
project: "<project ref>",
20+
build: {
21+
extensions: [lightpanda()],
22+
},
23+
});
24+
```
25+
26+
## Options
27+
28+
- `version`: The version of the browser to install. Default: `"latest"`.
29+
- `disableTelemetry`: Whether to disable telemetry. Default: `false`.
30+
31+
For example:
32+
33+
```ts trigger.config.ts
34+
import { defineConfig } from "@trigger.dev/sdk";
35+
import { lightpanda } from "@trigger.dev/build/extensions/lightpanda";
36+
37+
export default defineConfig({
38+
project: "<project ref>",
39+
build: {
40+
extensions: [
41+
lightpanda({
42+
version: "nightly",
43+
disableTelemetry: true,
44+
}),
45+
],
46+
},
47+
});
48+
```
49+
50+
## Development
51+
52+
When running in dev, you will first have to download the Lightpanda browser binary and make sure it's in your `PATH`. See [Lightpanda's installation guide](https://lightpanda.io/docs/getting-started/installation).
53+
54+
## Next steps
55+
56+
<CardGroup>
57+
<Card title="Lightpanda" color="#6ac6e2" icon="bolt" href="/guides/examples/lightpanda">
58+
Learn how to use Lightpanda in your project.
59+
</Card>
60+
</CardGroup>

docs/config/extensions/overview.mdx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ Trigger.dev provides a set of built-in extensions that you can use to customize
5050
| :-------------------------------------------------------------------- | :----------------------------------------------------------------------------- |
5151
| [prismaExtension](/config/extensions/prismaExtension) | Using prisma in your Trigger.dev tasks |
5252
| [pythonExtension](/config/extensions/pythonExtension) | Execute Python scripts in your project |
53-
| [playwright](/config/extensions/playwright) | Use Playwright in your Trigger.dev tasks |
5453
| [puppeteer](/config/extensions/puppeteer) | Use Puppeteer in your Trigger.dev tasks |
5554
| [ffmpeg](/config/extensions/ffmpeg) | Use FFmpeg in your Trigger.dev tasks |
5655
| [aptGet](/config/extensions/aptGet) | Install system packages in your build image |

docs/docs.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
"config/extensions/pythonExtension",
7979
"config/extensions/playwright",
8080
"config/extensions/puppeteer",
81+
"config/extensions/lightpanda",
8182
"config/extensions/ffmpeg",
8283
"config/extensions/aptGet",
8384
"config/extensions/additionalFiles",
@@ -362,6 +363,7 @@
362363
"guides/examples/fal-ai-realtime",
363364
"guides/examples/ffmpeg-video-processing",
364365
"guides/examples/firecrawl-url-crawl",
366+
"guides/examples/lightpanda",
365367
"guides/examples/libreoffice-pdf-conversion",
366368
"guides/examples/open-ai-with-retrying",
367369
"guides/examples/pdf-to-image",

docs/guides/examples/lightpanda.mdx

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
---
2+
title: "Lightpanda"
3+
sidebarTitle: "Lightpanda"
4+
description: "These examples demonstrate how to use Lightpanda with Trigger.dev."
5+
tag: "v4"
6+
---
7+
8+
import ScrapingWarning from "/snippets/web-scraping-warning.mdx";
9+
import UpgradeToV4Note from "/snippets/upgrade-to-v4-note.mdx";
10+
11+
<UpgradeToV4Note />
12+
13+
## Overview
14+
15+
Lightpanda is a purpose-built browser for AI and automation workflows. It is 10x faster, uses 10x less RAM than Chrome headless.
16+
17+
Here are a few examples of how to use Lightpanda with Trigger.dev.
18+
19+
<ScrapingWarning />
20+
21+
## Limitations
22+
23+
- Lightpanda does not support the `puppeteer` screenshot feature.
24+
25+
## Using Lightpanda Cloud
26+
27+
### Prerequisites
28+
29+
- A [Lightpanda](https://lightpanda.io/) cloud token
30+
31+
### Get links from a website
32+
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.
33+
34+
Make sure to add `LIGHTPANDA_TOKEN` to your Trigger.dev dashboard on the Environment Variables page:
35+
```bash
36+
LIGHTPANDA_TOKEN="<your-token>"
37+
```
38+
39+
```ts trigger/lightpanda-cloud-puppeteer.ts
40+
import { logger, task } from "@trigger.dev/sdk";
41+
import puppeteer from "puppeteer-core";
42+
43+
export const lightpandaCloudPuppeteer = task({
44+
id: "lightpanda-cloud-puppeteer",
45+
machine: {
46+
preset: "micro",
47+
},
48+
run: async (payload: { url: string }, { ctx }) => {
49+
logger.log("Lets get a page's links with Lightpanda!", { payload, ctx });
50+
51+
if (!payload.url) {
52+
logger.warn("Please define the payload url");
53+
throw new Error("payload.url is undefined");
54+
}
55+
56+
const token = process.env.LIGHTPANDA_TOKEN;
57+
if (!token) {
58+
logger.warn("Please define the env variable LIGHTPANDA_TOKEN");
59+
throw new Error("LIGHTPANDA_TOKEN is undefined");
60+
}
61+
62+
// Connect to Lightpanda's cloud
63+
const browser = await puppeteer.connect({
64+
browserWSEndpoint: `wss://cloud.lightpanda.io/ws?browser=lightpanda&token=${token}`,
65+
});
66+
const context = await browser.createBrowserContext();
67+
const page = await context.newPage();
68+
69+
// Dump all the links from the page.
70+
await page.goto(payload.url);
71+
72+
const links = await page.evaluate(() => {
73+
return Array.from(document.querySelectorAll("a")).map((row) => {
74+
return row.getAttribute("href");
75+
});
76+
});
77+
78+
logger.info("Processing done, shutting down…");
79+
80+
await page.close();
81+
await context.close();
82+
await browser.disconnect();
83+
84+
logger.info("✅ Completed");
85+
86+
return {
87+
links,
88+
};
89+
},
90+
});
91+
```
92+
93+
### Proxies
94+
95+
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.
96+
`datacenter` accepts an optional `country` query string parameter which is an [ISO 3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code.
97+
98+
```bash
99+
# This example will use a German IP
100+
wss://cloud.lightpanda.io/ws?proxy=datacenter&country=de&token=${token}
101+
```
102+
103+
### Session
104+
105+
A session is alive until you close it or the connection is closed. The max duration of a session is 15 minutes.
106+
107+
## Using Lightpanda browser directly
108+
109+
### Prerequisites
110+
111+
- Setup the [Lightpanda build extension](/config/extensions/lightpanda)
112+
113+
### Get the HTML of a webpage
114+
115+
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.
116+
117+
```ts trigger/lightpanda-fetch.ts
118+
import { logger, task } from "@trigger.dev/sdk";
119+
import { execSync } from "node:child_process";
120+
121+
export const lightpandaFetch = task({
122+
id: "lightpanda-fetch",
123+
machine: {
124+
preset: "micro",
125+
},
126+
run: async (payload: { url: string }, { ctx }) => {
127+
logger.log("Lets get a page's content with Lightpanda!", { payload, ctx });
128+
129+
if (!payload.url) {
130+
logger.warn("Please define the payload url");
131+
throw new Error("payload.url is undefined");
132+
}
133+
134+
const buffer = execSync(`lightpanda fetch --dump ${payload.url}`);
135+
136+
logger.info("✅ Completed");
137+
138+
return {
139+
message: buffer.toString(),
140+
};
141+
},
142+
});
143+
```
144+
145+
### Lightpanda CDP with Puppeteer
146+
147+
This task initializes a Lightpanda CDP server and uses it with `puppeteer-core` to scrape a provided URL.
148+
149+
```ts trigger/lightpanda-cdp.ts
150+
import { logger, task } from "@trigger.dev/sdk";
151+
import { spawn, type ChildProcessWithoutNullStreams } from "node:child_process";
152+
import puppeteer from "puppeteer-core";
153+
154+
const spawnLightpanda = async (host: string, port: string) =>
155+
new Promise<ChildProcessWithoutNullStreams>((resolve, reject) => {
156+
const child = spawn("lightpanda", [
157+
"serve",
158+
"--host",
159+
host,
160+
"--port",
161+
port,
162+
"--log_level",
163+
"info",
164+
]);
165+
166+
child.on("spawn", async () => {
167+
logger.info("Running Lightpanda's CDP server…", {
168+
pid: child.pid,
169+
});
170+
171+
await new Promise((resolve) => setTimeout(resolve, 250));
172+
resolve(child);
173+
});
174+
child.on("error", (e) => reject(e));
175+
});
176+
177+
export const lightpandaCDP = task({
178+
id: "lightpanda-cdp",
179+
machine: {
180+
preset: "micro",
181+
},
182+
run: async (payload: { url: string }, { ctx }) => {
183+
logger.log("Lets get a page's links with Lightpanda!", { payload, ctx });
184+
185+
if (!payload.url) {
186+
logger.warn("Please define the payload url");
187+
throw new Error("payload.url is undefined");
188+
}
189+
190+
const host = process.env.LIGHTPANDA_CDP_HOST ?? "127.0.0.1";
191+
const port = process.env.LIGHTPANDA_CDP_PORT ?? "9222";
192+
193+
// Launch Lightpanda's CDP server
194+
const lpProcess = await spawnLightpanda(host, port);
195+
196+
const browser = await puppeteer.connect({
197+
browserWSEndpoint: `ws://${host}:${port}`,
198+
});
199+
const context = await browser.createBrowserContext();
200+
const page = await context.newPage();
201+
202+
// Dump all the links from the page.
203+
await page.goto(payload.url);
204+
205+
const links = await page.evaluate(() => {
206+
return Array.from(document.querySelectorAll("a")).map((row) => {
207+
return row.getAttribute("href");
208+
});
209+
});
210+
211+
logger.info("Processing done");
212+
logger.info("Shutting down…");
213+
214+
// Close Puppeteer instance
215+
await browser.close();
216+
217+
// Stop Lightpanda's CDP Server
218+
lpProcess.kill();
219+
220+
logger.info("✅ Completed");
221+
222+
return {
223+
links,
224+
};
225+
},
226+
});
227+
```

docs/guides/introduction.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ Task code you can copy and paste to use in your project. They can all be extende
7171
| [FFmpeg video processing](/guides/examples/ffmpeg-video-processing) | Use FFmpeg to process a video in various ways and save it to Cloudflare R2. |
7272
| [Firecrawl URL crawl](/guides/examples/firecrawl-url-crawl) | Learn how to use Firecrawl to crawl a URL and return LLM-ready markdown. |
7373
| [LibreOffice PDF conversion](/guides/examples/libreoffice-pdf-conversion) | Convert a document to PDF using LibreOffice. |
74+
| [Lightpanda](/guides/examples/lightpanda) | Use Lightpanda browser (or cloud version) to get a webpage's content. |
7475
| [OpenAI with retrying](/guides/examples/open-ai-with-retrying) | Create a reusable OpenAI task with custom retry options. |
7576
| [PDF to image](/guides/examples/pdf-to-image) | Use `MuPDF` to turn a PDF into images and save them to Cloudflare R2. |
7677
| [Puppeteer](/guides/examples/puppeteer) | Use Puppeteer to generate a PDF or scrape a webpage. |

docs/images/intro-lightpanda.jpg

11.6 KB
Loading

docs/introduction.mdx

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -83,23 +83,24 @@ We provide everything you need to build and manage background tasks: a CLI and S
8383
<Card title="Supabase" img="/images/intro-supabase.jpg" href="/guides/examples/supabase-database-operations"/>
8484
<Card title="DALL•E" img="/images/intro-openai.jpg" href="/guides/examples/dall-e3-generate-image"/>
8585
<Card title="Firecrawl" img="/images/intro-firecrawl.jpg" href="/guides/examples/firecrawl-url-crawl"/>
86+
<Card title="Lightpanda" img="/images/intro-lightpanda.jpg" href="/guides/examples/lightpanda"/>
8687
</CardGroup>
8788

8889
## Explore by build extension
8990

90-
| Extension | What it does | Docs |
91-
|:----------|:------------|:--------------|
92-
| prismaExtension | Use Prisma with Trigger.dev | [Learn more](/config/extensions/prismaExtension) |
93-
| pythonExtension | Execute Python scripts in Trigger.dev | [Learn more](/config/extensions/pythonExtension) |
94-
| puppeteer | Use Puppeteer with Trigger.dev | [Learn more](/config/extensions/puppeteer) |
95-
| ffmpeg | Use FFmpeg with Trigger.dev | [Learn more](/config/extensions/ffmpeg) |
96-
| aptGet | Install system packages with aptGet | [Learn more](/config/extensions/aptGet) |
97-
| additionalFiles | Copy additional files to the build directory | [Learn more](/config/extensions/additionalFiles) |
98-
| additionalPackages | Include additional packages in the build | [Learn more](/config/extensions/additionalPackages) |
99-
| syncEnvVars | Automatically sync environment variables to Trigger.dev | [Learn more](/config/extensions/syncEnvVars) |
100-
| esbuildPlugin | Add existing or custom esbuild plugins to your build process | [Learn more](/config/extensions/esbuildPlugin) |
101-
| emitDecoratorMetadata | Support for the emitDecoratorMetadata TypeScript compiler | [Learn more](/config/extensions/emitDecoratorMetadata) |
102-
| audioWaveform | Support for Audio Waveform in your project | [Learn more](/config/extensions/audioWaveform) |
91+
| Extension | What it does | Docs |
92+
| :-------------------- | :----------------------------------------------------------- | :----------------------------------------------------- |
93+
| prismaExtension | Use Prisma with Trigger.dev | [Learn more](/config/extensions/prismaExtension) |
94+
| pythonExtension | Execute Python scripts in Trigger.dev | [Learn more](/config/extensions/pythonExtension) |
95+
| puppeteer | Use Puppeteer with Trigger.dev | [Learn more](/config/extensions/puppeteer) |
96+
| ffmpeg | Use FFmpeg with Trigger.dev | [Learn more](/config/extensions/ffmpeg) |
97+
| aptGet | Install system packages with aptGet | [Learn more](/config/extensions/aptGet) |
98+
| additionalFiles | Copy additional files to the build directory | [Learn more](/config/extensions/additionalFiles) |
99+
| additionalPackages | Include additional packages in the build | [Learn more](/config/extensions/additionalPackages) |
100+
| syncEnvVars | Automatically sync environment variables to Trigger.dev | [Learn more](/config/extensions/syncEnvVars) |
101+
| esbuildPlugin | Add existing or custom esbuild plugins to your build process | [Learn more](/config/extensions/esbuildPlugin) |
102+
| emitDecoratorMetadata | Support for the emitDecoratorMetadata TypeScript compiler | [Learn more](/config/extensions/emitDecoratorMetadata) |
103+
| audioWaveform | Support for Audio Waveform in your project | [Learn more](/config/extensions/audioWaveform) |
103104

104105
## Getting help
105106

0 commit comments

Comments
 (0)