Worker script
If you have both static assets and a Worker script configured, Cloudflare will first attempt to serve static assets if one matches the incoming request. You can read more about how we match assets in the HTML handling docs.
If an appropriate static asset if not found, Cloudflare will invoke your Worker script.
This allows you to easily combine together these two features to create powerful applications (e.g. a full-stack application, or a Single Page Application (SPA) or Static Site Generation (SSG) application with an API).
If you need to always run your Worker script before serving static assets, (for example, you wish to log requests, perform some authentication checks, use HTMLRewriter, or otherwise transform assets before serving), you can configure the assets.run_worker_first
setting. This will retain any other settings governing asset-serving behavior (e.g. assets.not_found_handling
) but gives you more control over exactly how and when those assets are served. This could be considered a platform-level "middleware" feature.
Once the Worker has been invoked, to then defer to static-asset serving, you can use an Assets binding:
{ "name": "my-worker", "compatibility_date": "2025-05-05", "main": "./worker/index.ts", "assets": { "directory": "./dist/", "binding": "ASSETS", "run_worker_first": true }}
name = "my-worker"compatibility_date = "2025-05-05"main = "./worker/index.ts"
[assets]directory = "./dist/"binding = "ASSETS"run_worker_first = true
import { 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); }}
Was this helpful?
- Resources
- API
- New to Cloudflare?
- Products
- Sponsorships
- Open Source
- Support
- Help Center
- System Status
- Compliance
- GDPR
- Company
- cloudflare.com
- Our team
- Careers
- 2025 Cloudflare, Inc.
- Privacy Policy
- Terms of Use
- Report Security Issues
- Trademark