Skip to content

Commit c084894

Browse files
authored
Create example-workers-binding-screenshots-from-web.mdx
make existing example into partial
1 parent 897e970 commit c084894

File tree

1 file changed

+167
-0
lines changed

1 file changed

+167
-0
lines changed
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
## 1. Create a Worker project
2+
3+
[Cloudflare Workers](/workers/) provides a serverless execution environment that allows you to create new applications or augment existing ones without configuring or maintaining infrastructure. Your Worker application is a container to interact with a headless browser to do actions, such as taking screenshots.
4+
5+
Create a new Worker project named `browser-worker` by running:
6+
7+
<PackageManagers
8+
type="create"
9+
pkg="cloudflare@latest"
10+
args={"browser-worker"}
11+
/>
12+
13+
<Render
14+
file="c3-post-run-steps"
15+
product="workers"
16+
params={{
17+
category: "hello-world",
18+
type: "Worker only",
19+
lang: "JavaScript / TypeScript",
20+
}}
21+
/>
22+
23+
## 2. Install Puppeteer
24+
25+
In your `browser-worker` directory, install Cloudflare’s [fork of Puppeteer](/browser-rendering/platform/puppeteer/):
26+
27+
<PackageManagers pkg="@cloudflare/puppeteer" dev />
28+
29+
## 3. Create a KV namespace
30+
31+
Browser Rendering can be used with other developer products. You might need a [relational database](/d1/), an [R2 bucket](/r2/) to archive your crawled pages and assets, a [Durable Object](/durable-objects/) to keep your browser instance alive and share it with multiple requests, or [Queues](/queues/) to handle your jobs asynchronous.
32+
33+
For the purpose of this guide, you are going to use a [KV store](/kv/concepts/kv-namespaces/) to cache your screenshots.
34+
35+
Create two namespaces, one for production, and one for development.
36+
37+
```sh
38+
npx wrangler kv namespace create BROWSER_KV_DEMO
39+
npx wrangler kv namespace create BROWSER_KV_DEMO --preview
40+
```
41+
42+
Take note of the IDs for the next step.
43+
44+
## 4. Configure the Wrangler configuration file
45+
46+
Configure your `browser-worker` project's [Wrangler configuration file](/workers/wrangler/configuration/) by adding a browser [binding](/workers/runtime-apis/bindings/) and a [Node.js compatibility flag](/workers/configuration/compatibility-flags/#nodejs-compatibility-flag). Bindings allow your Workers to interact with resources on the Cloudflare developer platform. Your browser `binding` name is set by you, this guide uses the name `MYBROWSER`. Browser bindings allow for communication between a Worker and a headless browser which allows you to do actions such as taking a screenshot, generating a PDF and more.
47+
48+
Update your [Wrangler configuration file](/workers/wrangler/configuration/) with the Browser Rendering API binding and the KV namespaces you created:
49+
50+
<WranglerConfig>
51+
52+
```toml title="wrangler.toml"
53+
name = "browser-worker"
54+
main = "src/index.js"
55+
compatibility_date = "2023-03-14"
56+
compatibility_flags = [ "nodejs_compat" ]
57+
58+
browser = { binding = "MYBROWSER" }
59+
kv_namespaces = [
60+
{ binding = "BROWSER_KV_DEMO", id = "22cf855786094a88a6906f8edac425cd", preview_id = "e1f8b68b68d24381b57071445f96e623" }
61+
]
62+
```
63+
64+
</WranglerConfig>
65+
66+
## 5. Code
67+
68+
<Tabs> <TabItem label="JavaScript" icon="seti:javascript">
69+
Update `src/index.js` with your Worker code:
70+
71+
```js
72+
import puppeteer from "@cloudflare/puppeteer";
73+
74+
export default {
75+
async fetch(request, env) {
76+
const { searchParams } = new URL(request.url);
77+
let url = searchParams.get("url");
78+
let img;
79+
if (url) {
80+
url = new URL(url).toString(); // normalize
81+
img = await env.BROWSER_KV_DEMO.get(url, { type: "arrayBuffer" });
82+
if (img === null) {
83+
const browser = await puppeteer.launch(env.MYBROWSER);
84+
const page = await browser.newPage();
85+
await page.goto(url);
86+
img = await page.screenshot();
87+
await env.BROWSER_KV_DEMO.put(url, img, {
88+
expirationTtl: 60 * 60 * 24,
89+
});
90+
await browser.close();
91+
}
92+
return new Response(img, {
93+
headers: {
94+
"content-type": "image/jpeg",
95+
},
96+
});
97+
} else {
98+
return new Response("Please add an ?url=https://example.com/ parameter");
99+
}
100+
},
101+
};
102+
```
103+
104+
</TabItem> <TabItem label="TypeScript" icon="seti:typescript">
105+
Update `src/index.ts` with your Worker code:
106+
107+
```ts
108+
import puppeteer from "@cloudflare/puppeteer";
109+
110+
interface Env {
111+
MYBROWSER: Fetcher;
112+
BROWSER_KV_DEMO: KVNamespace;
113+
}
114+
115+
export default {
116+
async fetch(request, env): Promise<Response> {
117+
const { searchParams } = new URL(request.url);
118+
let url = searchParams.get("url");
119+
let img: Buffer;
120+
if (url) {
121+
url = new URL(url).toString(); // normalize
122+
img = await env.BROWSER_KV_DEMO.get(url, { type: "arrayBuffer" });
123+
if (img === null) {
124+
const browser = await puppeteer.launch(env.MYBROWSER);
125+
const page = await browser.newPage();
126+
await page.goto(url);
127+
img = (await page.screenshot()) as Buffer;
128+
await env.BROWSER_KV_DEMO.put(url, img, {
129+
expirationTtl: 60 * 60 * 24,
130+
});
131+
await browser.close();
132+
}
133+
return new Response(img, {
134+
headers: {
135+
"content-type": "image/jpeg",
136+
},
137+
});
138+
} else {
139+
return new Response("Please add an ?url=https://example.com/ parameter");
140+
}
141+
},
142+
} satisfies ExportedHandler<Env>;
143+
```
144+
145+
</TabItem> </Tabs>
146+
147+
This Worker instantiates a browser using Puppeteer, opens a new page, navigates to what you put in the `"url"` parameter, takes a screenshot of the page, stores the screenshot in KV, closes the browser, and responds with the JPEG image of the screenshot.
148+
149+
If your Worker is running in production, it will store the screenshot to the production KV namespace. If you are running `wrangler dev`, it will store the screenshot to the dev KV namespace.
150+
151+
If the same `"url"` is requested again, it will use the cached version in KV instead, unless it expired.
152+
153+
## 6. Test
154+
155+
Run `npx wrangler dev` to test your Worker locally or run [`npx wrangler dev --remote`](/workers/wrangler/commands/#dev) to test your Worker remotely before deploying to Cloudflare's global network.
156+
157+
To test taking your first screenshot, go to the following URL:
158+
159+
`<LOCAL_HOST_URL>/?url=https://example.com`
160+
161+
## 7. Deploy
162+
163+
Run `npx wrangler deploy` to deploy your Worker to the Cloudflare global network.
164+
165+
To take your first screenshot, go to the following URL:
166+
167+
`<YOUR_WORKER>.<YOUR_SUBDOMAIN>.workers.dev/?url=https://example.com`

0 commit comments

Comments
 (0)