Fix Content Security Policy on Next.js
Last updated: April 2026
Next.js supports CSP via vercel.json, next.config.js, or Edge Middleware for nonce-based policies.
vercel.json โ static CSP
{
"headers": [
{
"source": "/(.*)",
"headers": [
{
"key": "Content-Security-Policy",
"value": "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data: https:; frame-ancestors 'none'; object-src 'none'"
}
]
}
]
}
next.config.js โ static CSP
const csp = [
"default-src 'self'",
"script-src 'self'",
"style-src 'self' 'unsafe-inline'",
"img-src 'self' data: https:",
"frame-ancestors 'none'",
"object-src 'none'",
].join('; ');
module.exports = {
async headers() {
return [{
source: '/(.*)',
headers: [{ key: 'Content-Security-Policy', value: csp }],
}];
},
};
Middleware โ nonce-based CSP
// middleware.ts
import { NextRequest, NextResponse } from 'next/server';
export function middleware(req: NextRequest) {
const nonce = Buffer.from(crypto.randomUUID()).toString('base64');
const csp = [
"default-src 'self'",
`script-src 'self' 'nonce-${nonce}' 'strict-dynamic'`,
`style-src 'self' 'nonce-${nonce}'`,
"frame-ancestors 'none'",
"object-src 'none'",
].join('; ');
const res = NextResponse.next({
request: { headers: new Headers({ ...Object.fromEntries(req.headers), 'x-nonce': nonce }) },
});
res.headers.set('Content-Security-Policy', csp);
return res;
}