Implement nonce-based CSP when Next.js support improves
Summary
Nonce-based Content Security Policy (CSP) was attempted but disabled because Next.js 14 doesn't fully support automatic nonce injection for its internal scripts.
Current State
- CSP is set via
next.config.jswith'unsafe-inline'for scripts and styles - CSP is in report-only mode for monitoring
- The middleware previously generated nonces but they weren't applied to Next.js internal scripts
Technical Details
Why Nonces Don't Work Currently
-
Next.js internal scripts (
__NEXT_DATA__, hydration scripts) don't automatically receive nonces -
style-src-attr(inline style attributes likestyle="...") don't support nonces at all - only<style>tags do - Edge runtime limitations - nonces work better with Node.js runtime
Research Findings (2026-01)
Per Next.js CSP documentation:
- Nonces require dynamic rendering (no static generation)
- Next.js can apply nonces automatically when:
- CSP header with nonce is set by proxy/middleware
-
x-nonceheader is set - Pages are dynamically rendered
- Experimental SRI (hash-based) is an alternative allowing static generation
Next.js 16 Status
Next.js 16 (released Oct 2025) doesn't include specific CSP improvements. The GitHub issue #55638 is closed as "completed" but with caveats about edge runtime and third-party scripts.
Future Work
When implementing nonce-based CSP:
- Ensure all pages using CSP are dynamically rendered
- Use Node.js runtime (not edge) in middleware/proxy
- Consider Next.js 16's new
proxy.tsinstead ofmiddleware.ts - Test thoroughly in report-only mode before enforcing
- Consider experimental SRI for static pages
Related Files
-
apps/blog/middleware.ts- Disabled nonce generation -
apps/blog/next.config.js- Current static CSP -
apps/blog/app/api/csp-report/route.ts- Violation reporting
References
- Next.js CSP Guide
- GitHub Issue #55638
- Internal notes:
NOTES/03-csp-internal.md