Static CSP headers
For applications that don’t require nonces, set CSP headers directly innext.config.js:
In development,
'unsafe-eval' is required because React uses eval for enhanced debugging. It’s not needed or used in production.Nonce-based CSP
A nonce is a unique, random string generated per request that allows specific inline scripts to run even under a strict CSP. This is more secure than'unsafe-inline' but requires dynamic rendering for every page.
Adding nonces with middleware
Generate a fresh nonce for each request in middleware and pass it as both a header and a CSP directive:How nonces work in Next.js
Pages must be dynamically rendered to use nonces (static pages have no request headers at build time). Here’s the flow:- Middleware generates a nonce and adds it to the
Content-Security-Policyandx-nonceheaders - During rendering, Next.js parses the CSP header and extracts the nonce from the
'nonce-{value}'pattern - Next.js automatically attaches the nonce to framework scripts, page bundles, inline styles, and
<Script>components
Forcing dynamic rendering for nonces
If a page doesn’t use dynamic APIs, opt it into dynamic rendering:Reading the nonce in a Server Component
Performance implications of nonces
Using nonces requires dynamic rendering for every page, which means:- Pages are generated on each request (no static caching)
- CDNs cannot cache dynamic pages by default
- Partial Prerendering (PPR) is incompatible with nonce-based CSP
'unsafe-inline' or when handling sensitive data.
Subresource Integrity (experimental)
As an alternative to nonces, Next.js supports hash-based CSP using Subresource Integrity (SRI). SRI generates cryptographic hashes of JavaScript files at build time, allowing static generation while maintaining strict CSP.- Pages can be statically generated and cached
- CDN-compatible
- Hashes are computed at build time
- Experimental; behavior may change
- App Router only
- Cannot handle dynamically generated scripts
