静的アセットと Worker スクリプトの両方を設定している場合、Cloudflare はまず、受信リクエストに一致する静的アセットがあればそれを返します。アセットの一致方法は HTML handling のドキュメント を参照してください。
適切な静的アセットが見つからない場合、Cloudflare は Worker スクリプトを呼び出します。
この 2 つの機能を組み合わせて、強力なアプリケーションを作れます(例: フルスタックアプリケーション、Single Page Application(SPA)、API 付きの Static Site Generation(SSG)アプリケーション)。
assets.run_worker_first 設定 で、静的アセット配信に対して Worker スクリプトをいつ実行するかを制御できます。アセットの配信方法とタイミングをより細かく制御でき、リクエストの「ミドルウェア」としても使えます。
静的アセットを返す前に、常に Worker スクリプトを実行したい場合(リクエストの記録、認証チェック、HTMLRewriter の利用、配信前のアセット変換など)は、run_worker_first を true にします。
{
"name": "my-worker",
// Set this to today's date
"compatibility_date": "2026-09-20",
"main": "./worker/index.ts",
"assets": {
"directory": "./dist/",
"binding": "ASSETS",
"run_worker_first": true
}
}name = "my-worker"
# Set this to today's date
compatibility_date = "2026-09-20"
main = "./worker/index.ts"
[assets]
directory = "./dist/"
binding = "ASSETS"
run_worker_first = trueimport { WorkerEntrypoint } from "cloudflare:workers";
export default class extends WorkerEntrypoint {
async fetch(request) {
// You can perform checks before fetching assets
const user = await checkIfRequestIsAuthenticated(request);
if (!user) {
return new Response("Unauthorized", { status: 401 });
}
// You can then just fetch the assets as normal, or you could pass in a custom Request object here if you wanted to fetch some other specific asset
const assetResponse = await this.env.ASSETS.fetch(request);
// You can return static asset response as-is, or you can transform them with something like HTMLRewriter
return new HTMLRewriter()
.on("#user", {
element(element) {
element.setInnerContent(JSON.stringify({ name: user.name }));
},
})
.transform(assetResponse);
}
}import { WorkerEntrypoint } from "cloudflare:workers";
export default class extends WorkerEntrypoint<Env> {
async fetch(request: Request) {
// You can perform checks before fetching assets
const user = await checkIfRequestIsAuthenticated(request);
if (!user) {
return new Response("Unauthorized", { status: 401 });
}
// You can then just fetch the assets as normal, or you could pass in a custom Request object here if you wanted to fetch some other specific asset
const assetResponse = await this.env.ASSETS.fetch(request);
// You can return static asset response as-is, or you can transform them with something like HTMLRewriter
return new HTMLRewriter()
.on("#user", {
element(element) {
element.setInnerContent(JSON.stringify({ name: user.name }));
},
})
.transform(assetResponse);
}
}ルートパターンの配列で、選択的に Worker 先行ルーティングを設定できます。多くの場合 single-page-application 設定 と組み合わせます。特定ルートだけ Worker を先に実行し、ほかのリクエストはデフォルトのアセット先行の動きにできます。
{
"name": "my-worker",
// Set this to today's date
"compatibility_date": "2026-09-20",
"main": "./worker/index.ts",
"assets": {
"directory": "./dist/",
"not_found_handling": "single-page-application",
"binding": "ASSETS",
"run_worker_first": ["/oauth/callback"]
}
}name = "my-worker"
# Set this to today's date
compatibility_date = "2026-09-20"
main = "./worker/index.ts"
[assets]
directory = "./dist/"
not_found_handling = "single-page-application"
binding = "ASSETS"
run_worker_first = [ "/oauth/callback" ]import { WorkerEntrypoint } from "cloudflare:workers";
export default class extends WorkerEntrypoint {
async fetch(request) {
// The only thing this Worker script does is handle an OAuth callback.
// All other requests either serve an asset that matches or serve the index.html fallback, without ever hitting this code.
const url = new URL(request.url);
const code = url.searchParams.get("code");
const state = url.searchParams.get("state");
const accessToken = await exchangeCodeForToken(code, state);
const sessionIdentifier = await storeTokenAndGenerateSession(accessToken);
// Redirect back to the index, but set a cookie that the front-end will use.
return new Response(null, {
headers: {
Location: "/",
"Set-Cookie": `session_token=${sessionIdentifier}; HttpOnly; Secure; SameSite=Lax; Path=/`,
},
});
}
}import { WorkerEntrypoint } from "cloudflare:workers";
export default class extends WorkerEntrypoint<Env> {
async fetch(request: Request) {
// The only thing this Worker script does is handle an OAuth callback.
// All other requests either serve an asset that matches or serve the index.html fallback, without ever hitting this code.
const url = new URL(request.url);
const code = url.searchParams.get("code");
const state = url.searchParams.get("state");
const accessToken = await exchangeCodeForToken(code, state);
const sessionIdentifier = await storeTokenAndGenerateSession(accessToken);
// Redirect back to the index, but set a cookie that the front-end will use.
return new Response(null, {
headers: {
Location: "/",
"Set-Cookie": `session_token=${sessionIdentifier}; HttpOnly; Secure; SameSite=Lax; Path=/`,
},
});
}
}