このガイドでは、Browser Run API を使って Web ページのスクリーンショットを取得する Worker を作成します。ブラウザ自動化の一般的な用途です。
- Cloudflare アカウント ↗ に登録します。
Node.js↗ をインストールします。
Node.js のバージョンマネージャー
権限の問題を避け、Node.js のバージョンを切り替えられるよう、Volta ↗ や nvm ↗ などの Node バージョンマネージャーを使います。このガイドの後半で説明する Wrangler には、Node バージョン 16.17.0 以降が必要です。
Cloudflare Workers は、インフラの設定や運用なしに、新しいアプリケーションの作成や既存アプリの拡張ができるサーバーレス実行環境です。Worker アプリケーションは、ヘッドレスブラウザーとやり取りしてスクリーンショット撮影などの操作を行うコンテナになります。
次のコマンドで、browser-worker という名前の新しい Worker プロジェクトを作成します。
npm create cloudflare@latest -- browser-workeryarn create cloudflare browser-workerpnpm create cloudflare@latest browser-workerセットアップでは、次のオプションを選びます。
- What would you like to start with? では、
Hello World exampleを選びます。 - Which template would you like to use? では、
Worker onlyを選びます。 - Which language do you want to use? では、
JavaScript / TypeScriptを選びます。 - Do you want to use git for version control? では、
Yesを選びます。 - Do you want to deploy your application? では、
Noを選びます(デプロイ前にいくつか変更します)。
browser-worker ディレクトリで、Cloudflare の Puppeteer フォーク をインストールします。
npm i -D @cloudflare/puppeteeryarn add -D @cloudflare/puppeteerpnpm add -D @cloudflare/puppeteerbun add -d @cloudflare/puppeteerBrowser Run は、ほかの開発者向け製品と組み合わせて使えます。クロールしたページやアセットを保存する リレーショナルデータベース や R2 バケット、ブラウザーインスタンスを生かしたまま複数リクエストで共有する Durable Object、ジョブを非同期で処理する Queues が必要になることがあります。
この例では、スクリーンショットのキャッシュに KV ストア を使います。
本番用と開発用の 2 つの名前空間を作成します。
npx wrangler kv namespace create BROWSER_KV_DEMO
npx wrangler kv namespace create BROWSER_KV_DEMO --preview次の手順で使うため、ID を控えておきます。
browser-worker プロジェクトの Wrangler 設定ファイル に、ブラウザー バインディング と Node.js 互換フラグ を追加します。バインディングを使うと、Worker は Cloudflare 開発者プラットフォーム上のリソースと連携できます。ブラウザーの binding 名は自分で決めます。このガイドでは MYBROWSER を使います。ブラウザーバインディングは Worker とヘッドレスブラウザーの通信を可能にし、スクリーンショット撮影、PDF 生成などの操作ができます。
Wrangler 設定ファイル を、Browser Run API バインディングと作成した KV 名前空間で更新します。
{
"$schema": "./node_modules/wrangler/config-schema.json",
"name": "browser-worker",
"main": "src/index.js",
// Set this to today's date
"compatibility_date": "2026-09-20",
"compatibility_flags": ["nodejs_compat"],
"browser": {
"binding": "MYBROWSER"
},
"kv_namespaces": [
{
"binding": "BROWSER_KV_DEMO",
"id": "22cf855786094a88a6906f8edac425cd",
"preview_id": "e1f8b68b68d24381b57071445f96e623"
}
]
}"$schema" = "./node_modules/wrangler/config-schema.json"
name = "browser-worker"
main = "src/index.js"
# Set this to today's date
compatibility_date = "2026-09-20"
compatibility_flags = [ "nodejs_compat" ]
[browser]
binding = "MYBROWSER"
[[kv_namespaces]]
binding = "BROWSER_KV_DEMO"
id = "22cf855786094a88a6906f8edac425cd"
preview_id = "e1f8b68b68d24381b57071445f96e623"src/index.js を、次の Worker コードで更新します。
import puppeteer from "@cloudflare/puppeteer";
export default {
async fetch(request, env) {
const { searchParams } = new URL(request.url);
let url = searchParams.get("url");
let img;
if (url) {
url = new URL(url).toString(); // normalize
img = await env.BROWSER_KV_DEMO.get(url, { type: "arrayBuffer" });
if (img === null) {
const browser = await puppeteer.launch(env.MYBROWSER);
const page = await browser.newPage();
await page.goto(url);
img = await page.screenshot();
await env.BROWSER_KV_DEMO.put(url, img, {
expirationTtl: 60 * 60 * 24,
});
await browser.close();
}
return new Response(img, {
headers: {
"content-type": "image/jpeg",
},
});
} else {
return new Response("Please add an ?url=https://example.com/ parameter");
}
},
};src/index.ts を、次の Worker コードで更新します。
import puppeteer from "@cloudflare/puppeteer";
interface Env {
MYBROWSER: Fetcher;
BROWSER_KV_DEMO: KVNamespace;
}
export default {
async fetch(request, env): Promise<Response> {
const { searchParams } = new URL(request.url);
let url = searchParams.get("url");
let img: Buffer;
if (url) {
url = new URL(url).toString(); // normalize
img = await env.BROWSER_KV_DEMO.get(url, { type: "arrayBuffer" });
if (img === null) {
const browser = await puppeteer.launch(env.MYBROWSER);
const page = await browser.newPage();
await page.goto(url);
img = (await page.screenshot()) as Buffer;
await env.BROWSER_KV_DEMO.put(url, img, {
expirationTtl: 60 * 60 * 24,
});
await browser.close();
}
return new Response(img, {
headers: {
"content-type": "image/jpeg",
},
});
} else {
return new Response("Please add an ?url=https://example.com/ parameter");
}
},
} satisfies ExportedHandler<Env>;この Worker は Puppeteer でブラウザーを起動し、新しいページを開き、url パラメーターの場所へ移動してスクリーンショットを撮影します。スクリーンショットを KV に保存し、ブラウザーを閉じて、JPEG 画像として返します。
Worker が本番で動いている場合は、本番用の KV 名前空間にスクリーンショットを保存します。wrangler dev を実行している場合は、開発用の KV 名前空間に保存します。
同じ url が再度リクエストされた場合は、期限切れでなければ KV のキャッシュを使います。
Worker をローカルでテストするには、npx wrangler dev を実行します。
最初のスクリーンショットをテストするには、次の URL を開きます。
<LOCAL_HOST_URL>/?url=https://example.com
Worker を Cloudflare のグローバルネットワークへデプロイするには、npx wrangler deploy を実行します。
最初のスクリーンショットを撮影するには、次の URL を開きます。
<YOUR_WORKER>.<YOUR_SUBDOMAIN>.workers.dev/?url=https://example.com- そのほかの Puppeteer の例 ↗