If your application doesn’t rely on inline scripts, you can configure CSP headers directly in next.config.js:
const cspHeader = `
default-src 'self';
script-src 'self' 'unsafe-eval' 'unsafe-inline';
style-src 'self' 'unsafe-inline';
img-src 'self' blob: data:;
font-src 'self';
object-src 'none';
base-uri 'self';
form-action 'self';
frame-ancestors 'none';
upgrade-insecure-requests;
`
module.exports = {
async headers() {
return [
{
source: '/(.*)',
headers: [
{
key: 'Content-Security-Policy',
value: cspHeader.replace(/\n/g, ''),
},
],
},
]
},
}Next.js offers experimental support for SRI, allowing hash-based CSP enforcement without dynamic rendering.
Add the following to next.config.js:
const nextConfig = {
experimental: {
sri: {
algorithm: 'sha256',
},
},
}
module.exports = nextConfigSRI works independently by adding integrity hashes to your scripts. You can keep your CSP strict:
const cspHeader = `
default-src 'self';
script-src 'self';
style-src 'self';
img-src 'self' blob: data:;
font-src 'self';
object-src 'none';
base-uri 'self';
form-action 'self';
frame-ancestors 'none';
upgrade-insecure-requests;
`
module.exports = {
experimental: {
sri: {
algorithm: 'sha256',
},
},
async headers() {
return [
{
source: '/(.*)',
headers: [
{
key: 'Content-Security-Policy',
value: cspHeader.replace(/\n/g, ''),
},
],
},
]
},
}In development, you may need 'unsafe-eval' for debugging tools:
const isDev = process.env.NODE_ENV === 'development'
const cspHeader = `
default-src 'self';
script-src 'self' 'nonce-${nonce}' 'strict-dynamic' ${isDev ? "'unsafe-eval'" : ''};
style-src 'self' ${isDev ? "'unsafe-inline'" : `'nonce-${nonce}'`};
...
`To use services like Google Tag Manager:
import { GoogleTagManager } from '@next/third-parties/google'
import { headers } from 'next/headers'
export default async function RootLayout({ children }) {
const nonce = (await headers()).get('x-nonce')
return (
<html lang="en">
<body>
{children}
<GoogleTagManager gtmId="GTM-XYZ" nonce={nonce} />
</body>
</html>
)
}const cspHeader = `
default-src 'self';
script-src 'self' 'nonce-${nonce}' 'strict-dynamic' https://www.googletagmanager.com;
connect-src 'self' https://www.google-analytics.com;
img-src 'self' data: https://www.google-analytics.com;
`script-src'wasm-unsafe-eval' if needed| Version | Changes |
|---|---|
| v14.0.0 | Experimental SRI support added for hash-based CSP |
| v13.4.20 | Recommended for proper nonce handling and CSP header parsing |
If your application doesn’t require nonce-based CSP, you can use SRI and direct CSP headers to maintain security while benefiting from static rendering and CDN caching. This approach is ideal for performance-focused applications with build-time integrity needs.