Deployloading...
☁️

CF Workers SPA Routing Showcase

Path-based demo of Cloudflare Workers run_worker_first for SPA routing. Compare broken (HTML everywhere) vs fixed (proper 404 for assets).

→ Broken

/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.

What gets compared

Script load.js chunk → broken: HTML (MIME error) / fixed: 404
Dynamic importimport() → broken: HTML / fixed: 404
Fetch request.json file → broken: HTML / fixed: 404
Navigation/foo/bar/route → both: index.html (platform SPA fallback)

Config

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

Routing Flow

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.