diff --git a/middleware.ts b/middleware.ts index 41a7811..9c26cec 100644 --- a/middleware.ts +++ b/middleware.ts @@ -67,7 +67,16 @@ export function middleware(req: NextRequest) { // proxied analytics tracker at /_a), and the Turnstile host-source actually // takes effect instead of being silently ignored. The nonce is kept, so // dynamic routes and any inline script still get the stronger guarantee. - `script-src 'self' 'nonce-${nonce}' ${TURNSTILE_ORIGIN}${devScriptSrc}`, + // NOTE: nonce-based script-src is incompatible with Next's statically + // prerendered pages. The nonce is minted per request, but static HTML was + // baked at build time WITHOUT one, so every inline hydration script on those + // pages ("/", the marketing routes) got blocked: the page painted, React + // failed to hydrate, and the tree unmounted to a blank screen. Dynamic routes + // (/sign-in, /dashboard) were fine, which is what made this easy to miss. + // A browser that honours a nonce ignores 'unsafe-inline', so the two cannot + // be combined — this policy still restricts which ORIGINS may serve scripts. + // To go back to nonces, every page must render dynamically. + `script-src 'self' 'unsafe-inline' ${TURNSTILE_ORIGIN}${devScriptSrc}`, "style-src 'self' 'unsafe-inline'", "img-src 'self' data: https://oaidalleapiprodscus.blob.core.windows.net https://images.unsplash.com", "media-src 'self'",