Next.js
Next.js has the most complete CSP story of any framework here, and also the most honest one: it documents not just how to add a nonce, but what adopting one costs you. That trade-off is the thing to understand before you start.
What Next.js gives you
- Nonce generation in the proxy layer (
proxy.ts, previously middleware), set on both theContent-Security-Policyheader and a customx-nonceheader. - Automatic nonce application during server-side rendering. Next.js parses the CSP header, extracts the
'nonce-{value}'pattern, and attaches it to framework scripts, page bundles, its own inline styles and scripts, and any<Script>component - you do not tag them by hand. headers()in a Server Component for reading the nonce back, e.g. to pass to<GoogleTagManager nonce={nonce} />.- A no-nonce route: set the header statically in
next.config.jsvia theheaders()config. - Experimental hash-based CSP via Subresource Integrity, which keeps static generation intact.
Setting the header
Report-only is the safe starting point. Your URL comes from the Setup page:
const cspHeader = `
default-src 'self';
script-src 'self' 'nonce-${nonce}' 'strict-dynamic';
object-src 'none';
base-uri 'self';
report-uri https://abc123.report-uri.com/r/d/csp/reportOnly;
`
response.headers.set(
'Content-Security-Policy-Report-Only',
cspHeader.replace(/\s{2,}/g, ' ').trim(),
)
Filter the proxy with a matcher so it skips API routes, _next/static, _next/image and prefetches - those do not need the header and generating a nonce for them is wasted work.
Things to watch for
- Nonces force dynamic rendering. Static optimisation and ISR are disabled, pages cannot be CDN-cached by default, and Partial Prerendering is incompatible because the static shell has no access to the nonce. This is a real architectural cost, not a footnote.
'unsafe-eval'is required in development because React usesevalfor better error stacks. It is not required in production - gate it onNODE_ENVrather than shipping it.- If you need to keep static generation, the experimental SRI support is the alternative: hashes are generated at build time and added as
integrityattributes, so pages stay cacheable. - A
<meta>tag policy cannot carryreport-uriorreport-to. If you want reports, the policy has to be a header.
Official documentation
Next.js - How to set a Content Security Policy (CSP) for your Next.js application
Start Monitoring with Report URI
Already using us for CSP? Find your report-uri value on Setup, or view your CSP reports.
New to Report URI? Create an account and grab your report-uri value from the Setup page.