Fix Missing Security Headers on Vercel
Last updated: April 2026
Vercel does not add security headers by default. Add them via vercel.json or next.config.js for Next.js projects. Both approaches apply headers at the edge on every response.
vercel.json โ all security headers
{
"headers": [
{
"source": "/(.*)",
"headers": [
{
"key": "Strict-Transport-Security",
"value": "max-age=31536000; includeSubDomains"
},
{
"key": "X-Frame-Options",
"value": "SAMEORIGIN"
},
{
"key": "X-Content-Type-Options",
"value": "nosniff"
},
{
"key": "Referrer-Policy",
"value": "strict-origin-when-cross-origin"
},
{
"key": "Permissions-Policy",
"value": "camera=(), microphone=(), geolocation=()"
},
{
"key": "Content-Security-Policy",
"value": "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; frame-ancestors 'none'; object-src 'none'"
}
]
}
]
}
Next.js โ next.config.js alternative
// next.config.js
const securityHeaders = [
{ key: 'Strict-Transport-Security', value: 'max-age=31536000; includeSubDomains' },
{ key: 'X-Frame-Options', value: 'SAMEORIGIN' },
{ key: 'X-Content-Type-Options', value: 'nosniff' },
{ key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
{ key: 'Permissions-Policy', value: 'camera=(), microphone=(), geolocation=()' },
];
module.exports = {
async headers() {
return [{ source: '/(.*)', headers: securityHeaders }];
},
};
API routes โ different headers
{
"headers": [
{
"source": "/api/(.*)",
"headers": [
{ "key": "X-Content-Type-Options", "value": "nosniff" },
{ "key": "Cache-Control", "value": "no-store" }
]
},
{
"source": "/(.*)",
"headers": [
{ "key": "X-Frame-Options", "value": "SAMEORIGIN" },
{ "key": "Strict-Transport-Security", "value": "max-age=31536000" }
]
}
]
}
Deploy and verify
# Deploy npx vercel --prod # Verify headers curl -sI https://yourapp.vercel.app | grep -iE "strict|x-frame|x-content|referrer|permissions|content-security"