### Common Patterns **1. Forward request to assets:** ```typescript export default { async fetch(request: Request, env: Env): Promise { return env.ASSETS.fetch(request); } }; ``` **2. Fetch specific asset by path:** ```typescript const response = await env.ASSETS.fetch("https://assets.local/logo.png"); ``` **3. Modify request before fetching asset:** ```typescript const url = new URL(request.url); url.pathname = "/index.html"; return env.ASSETS.fetch(new Request(url, request)); ``` **4. Transform asset response:** ```typescript const response = await env.ASSETS.fetch(request); const modifiedResponse = new Response(response.body, response); modifiedResponse.headers.set("X-Custom-Header", "value"); modifiedResponse.headers.set("Cache-Control", "public, max-age=3600"); return modifiedResponse; ``` **5. Conditional asset serving:** ```typescript export default { async fetch(request: Request, env: Env): Promise { const url = new URL(request.url); if (url.pathname === '/') { return env.ASSETS.fetch('/index.html'); } return env.ASSETS.fetch(request); } }; ``` **6. SPA with API routes:** Most common full-stack pattern - static SPA with backend API: ```typescript export default { async fetch(request: Request, env: Env): Promise { const url = new URL(request.url); if (url.pathname.startsWith('/api/')) { return handleAPI(request, env); } return env.ASSETS.fetch(request); } }; async function handleAPI(request: Request, env: Env): Promise { return new Response(JSON.stringify({ status: 'ok' }), { headers: { 'Content-Type': 'application/json' } }); } ``` **Config:** Set `run_worker_first: ["/api/*"]` (see configuration.md:66-106) **7. Auth gating for protected assets:** ```typescript export default { async fetch(request: Request, env: Env): Promise { const url = new URL(request.url); if (url.pathname.startsWith('/admin/')) { const session = await validateSession(request, env); if (!session) { return Response.redirect('/login', 302); } } return env.ASSETS.fetch(request); } }; ``` **Config:** Set `run_worker_first: ["/admin/*"]` **8. Custom headers for security:** ```typescript export default { async fetch(request: Request, env: Env): Promise { const response = await env.ASSETS.fetch(request); const secureResponse = new Response(response.body, response); secureResponse.headers.set('X-Frame-Options', 'DENY'); secureResponse.headers.set('X-Content-Type-Options', 'nosniff'); secureResponse.headers.set('Content-Security-Policy', "default-src 'self'"); return secureResponse; } }; ``` **9. A/B testing via cookies:** ```typescript export default { async fetch(request: Request, env: Env): Promise { const cookies = request.headers.get('Cookie') || ''; const variant = cookies.includes('variant=b') ? 'b' : 'a'; const url = new URL(request.url); if (url.pathname === '/') { return env.ASSETS.fetch(`/index-${variant}.html`); } return env.ASSETS.fetch(request); } }; ``` **10. Locale-based routing:** ```typescript export default { async fetch(request: Request, env: Env): Promise { const locale = request.headers.get('Accept-Language')?.split(',')[0] || 'en'; const url = new URL(request.url); if (url.pathname === '/') { return env.ASSETS.fetch(`/${locale}/index.html`); } if (!url.pathname.startsWith(`/${locale}/`)) { url.pathname = `/${locale}${url.pathname}`; } return env.ASSETS.fetch(url); } }; ``` **11. OAuth callback handling:** ```typescript export default { async fetch(request: Request, env: Env): Promise { const url = new URL(request.url); if (url.pathname === '/auth/callback') { const code = url.searchParams.get('code'); if (code) { const session = await exchangeCode(code, env); return new Response(null, { status: 302, headers: { 'Location': '/', 'Set-Cookie': `session=${session}; HttpOnly; Secure; SameSite=Lax` } }); } } return env.ASSETS.fetch(request); } }; ``` **Config:** Set `run_worker_first: ["/auth/*"]` **12. Cache control override:** ```typescript export default { async fetch(request: Request, env: Env): Promise { const response = await env.ASSETS.fetch(request); const url = new URL(request.url); // Immutable assets (hashed filenames) if (/\.[a-f0-9]{8,}\.(js|css|png|jpg)$/.test(url.pathname)) { return new Response(response.body, { ...response, headers: { ...Object.fromEntries(response.headers), 'Cache-Control': 'public, max-age=31536000, immutable' } }); } return response; } }; ```