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.js with '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

  1. Next.js internal scripts (__NEXT_DATA__, hydration scripts) don't automatically receive nonces
  2. style-src-attr (inline style attributes like style="...") don't support nonces at all - only <style> tags do
  3. 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-nonce header 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:

  1. Ensure all pages using CSP are dynamically rendered
  2. Use Node.js runtime (not edge) in middleware/proxy
  3. Consider Next.js 16's new proxy.ts instead of middleware.ts
  4. Test thoroughly in report-only mode before enforcing
  5. Consider experimental SRI for static pages
  • 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