Path-based demo of Cloudflare Workers run_worker_first for SPA routing. Compare broken (HTML everywhere) vs fixed (proper 404 for assets).
/assets/broken/* routes to Worker. Worker returns index.html for every request — .js chunks and .json files get text/html → MIME type errors.
→ Fixed/assets/fixed/* routes to Worker. Worker returns 404 for static file extensions (.js, .css, .json). Navigation routes still get SPA fallback.
wrangler.toml run_worker_first = ["/assets/broken/*", "/assets/fixed/*"] not_found_handling = "single-page-application" workers/app.ts /assets/broken/* → always serve index.html /assets/fixed/* → check extension → 404 if static, else index.html /* (everything else) → ASSETS.fetch → 404 → SPA fallback
Navigation requests (browser page loads) → platform serves index.html directly via not_found_handling — zero Worker cost.
/assets/broken/* and /assets/fixed/* → hit Worker first via run_worker_first.
Everything else → Worker fallthrough path → try ASSETS first, SPA fallback if not found.