fix(csp): blank page on statically prerendered routes
The nonce-based script-src is incompatible with Next's static prerendering. The nonce is minted per request in middleware, but statically generated HTML was produced at build time with no nonce on its inline scripts, so on "/" and the marketing routes every inline hydration script was blocked: the page painted from SSR HTML, React failed to hydrate, and the tree unmounted to a blank screen a moment later. Dynamic routes (/sign-in, /dashboard) render per request, receive the nonce, and worked — which is why this was missed. Browsers that honour a nonce ignore 'unsafe-inline', so the two cannot be combined. Drop the nonce and allow inline scripts; the policy still restricts which origins may serve scripts, and frame-src/connect-src stay strict. Restoring nonces would require every route to render dynamically. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
fc00ad5b32
commit
68c0b1306d
+10
-1
@@ -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'",
|
||||
|
||||
Reference in New Issue
Block a user