HTML、CSS、画像などの静的アセットを Worker の一部としてアップロードできます。キャッシュとウェブブラウザへの配信は Cloudflare が行います。
CLI から始める — API Worker 付きの React SPA を足場として作り、Cloudflare Vite plugin を使います。
npm create cloudflare@latest -- my-react-app --framework=reactyarn create cloudflare my-react-app --framework=reactpnpm create cloudflare@latest my-react-app --framework=reactまたは Cloudflare にそのままデプロイする
Workers で使えるフレームワークについて、詳しくはこちらです。
対応フレームワーク
プロジェクトをデプロイすると、Cloudflare は Worker のコードと静的アセットを 1 回の操作でデプロイします。このデプロイは、静的ファイルのホスティング、カスタムロジック、グローバルキャッシュを組み合わせた、密結合の「ユニット」として Cloudflare のネットワーク上で動きます。
この設計の中心は、Wrangler 設定ファイル で指定する アセットディレクトリ です。デプロイ時、Wrangler はこのディレクトリのファイルを Cloudflare のインフラへ自動アップロードします。デプロイ後、これらのアセットへのリクエストは、ユーザーに最も近い拠点へ効率よくルーティングされます。
{
"$schema": "./node_modules/wrangler/config-schema.json",
"name": "my-spa",
"main": "src/index.js",
// Set this to today's date
"compatibility_date": "2026-09-20",
"assets": {
"directory": "./dist",
"binding": "ASSETS"
}
}"$schema" = "./node_modules/wrangler/config-schema.json"
name = "my-spa"
main = "src/index.js"
# Set this to today's date
compatibility_date = "2026-09-20"
[assets]
directory = "./dist"
binding = "ASSETS"アセットバインディング を追加すると、Worker のコード内からアセットを直接 fetch して配信できます。
// index.js
export default {
async fetch(request, env) {
const url = new URL(request.url);
if (url.pathname.startsWith("/api/")) {
return new Response(JSON.stringify({ name: "Cloudflare" }), {
headers: { "Content-Type": "application/json" },
});
}
return env.ASSETS.fetch(request);
},
};from workers import WorkerEntrypoint, Response
from urllib.parse import urlparse
class Default(WorkerEntrypoint):
async def fetch(self, request):
# Example of serving static assets
url = urlparse(request.url)
if url.path.startswith("/api/):
return Response.json({"name": "Cloudflare"})
return await self.env.ASSETS.fetch(request)既定では、リクエストされた URL が静的アセットディレクトリ内のファイルに一致する場合、そのファイルが配信されます。Worker のコードは呼び出されません。一致するアセットがなく、Worker スクリプトがある場合は、Worker がリクエストを処理します。Worker はレスポンスを返すか、アセットバインディング(例: env.ASSETS.fetch(request))で静的アセットに再度委ねるかを選べます。Worker スクリプトがなければ、404 Not Found レスポンスを返します。
静的アセットに一致しないリクエストの既定動作は、Wrangler 設定ファイルの assets 配下の not_found_handling オプション で変更できます。
not_found_handling = "single-page-application": 静的アセットに一致しないリクエストに対し、index.htmlを付けた200 OKレスポンスを返すようにします。シングルページアプリケーション(SPA)の場合に使います。高度なルーティング制御 では、run_worker_firstによる選択的ルーティングとの併用を推奨します。not_found_handling = "404-page": 静的アセットに一致しないリクエストに対し、最も近い404.htmlを付けた404 Not Foundレスポンスを返すようにします。
{
"assets": {
"directory": "./dist",
"not_found_handling": "single-page-application"
}
}[assets]
directory = "./dist"
not_found_handling = "single-page-application"アセットを配信する前に Worker のコードを実行したい場合は、run_worker_first オプションを使います。true にするとすべてのリクエストで Worker スクリプトを呼び出します。ルートパターンの配列にすると、選択したパスだけで Worker スクリプトを先に実行できます。
特定のパスで Worker スクリプトを呼び出す:
{
"name": "my-spa-worker",
// Set this to today's date
"compatibility_date": "2026-09-20",
"main": "./src/index.ts",
"assets": {
"directory": "./dist/",
"not_found_handling": "single-page-application",
"binding": "ASSETS",
"run_worker_first": ["/api/*", "!/api/docs/*"]
}
}name = "my-spa-worker"
# Set this to today's date
compatibility_date = "2026-09-20"
main = "./src/index.ts"
[assets]
directory = "./dist/"
not_found_handling = "single-page-application"
binding = "ASSETS"
run_worker_first = [ "/api/*", "!/api/docs/*" ]より高度なパターンは、bootstrap データ付き SPA シェル を参照してください。HTMLRewriter で、事前取得した API データを HTML ストリームへ注入します。
ルーティングオプション
Cloudflare はネットワーク全体で静的アセットを自動キャッシュし、世界中のユーザーへ速く届けます。静的アセットがリクエストされると、以降のリクエスト向けに自動でキャッシュされます。
-
最初のリクエスト: アセットが初めてリクエストされると、ストレージから取得され、最も近い Cloudflare 拠点にキャッシュされます。
-
以降のリクエスト: 同じアセットのリクエストが、キャッシュを持たないデータセンターに届いた場合、Cloudflare の Tiered Cache により、ストレージへ戻らず近くのキャッシュから取得できます。キャッシュヒット率が上がり、遅延が減り、不要なオリジン取得も減ります。