How to add security headers to a Next.js or Vercel app
Security headers are instructions your server sends with every page, telling the browser to refuse risky behavior: loading your site in someone else's frame, guessing file types, or downgrading to plain HTTP. AI tools rarely add them, and they take a few minutes to set up.
1. Check what your site sends today
Run this from a terminal, swapping in your domain:
curl -sI https://your-app.com | grep -iE 'strict-transport|content-security|x-frame|x-content-type|referrer-policy|permissions-policy'Any header missing from the output is not being sent. You can also open DevTools, go to the Network tab, reload, click the first request and read its response headers.
2. Know what each header does
- Strict-Transport-Security tells browsers to use HTTPS only for your domain. Vercel already sends it on its own domains, but check your custom domain.
- X-Content-Type-Options: nosniff stops the browser from treating an uploaded file as a script.
- X-Frame-Options: DENY (or
frame-ancestors 'none'in a CSP) stops other sites from loading yours in a hidden frame to trick clicks. - Referrer-Policy: strict-origin-when-cross-origin keeps full URLs, which can contain tokens or IDs, from leaking to other sites.
- Permissions-Policy turns off browser features you do not use, such as the camera, microphone or location.
- Content-Security-Policy lists where scripts, styles and requests may come from. It is the strongest defense against cross-site scripting and the easiest to get wrong, so add it last.
3. Add them in Next.js
In next.config.js, return the headers for every route:
const securityHeaders = [
{ key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubDomains; preload' },
{ key: 'X-Content-Type-Options', value: 'nosniff' },
{ key: 'X-Frame-Options', value: 'DENY' },
{ key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
{ key: 'Permissions-Policy', value: 'camera=(), microphone=(), geolocation=()' },
];
module.exports = {
async headers() {
return [{ source: '/:path*', headers: securityHeaders }];
},
};Only add preload to HSTS if every subdomain you own serves HTTPS, because browsers will refuse plain HTTP for all of them.
4. Or add them on Vercel or Netlify for any framework
For a Vite, React or static app on Vercel, put the same headers in vercel.json:
{
"headers": [
{ "source": "/(.*)", "headers": [
{ "key": "X-Content-Type-Options", "value": "nosniff" },
{ "key": "X-Frame-Options", "value": "DENY" },
{ "key": "Referrer-Policy", "value": "strict-origin-when-cross-origin" },
{ "key": "Permissions-Policy", "value": "camera=(), microphone=(), geolocation=()" }
] }
]
}On Netlify, add a _headers file to your published folder:
/*
X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()5. Add a Content-Security-Policy safely
Start in report-only mode so nothing breaks. Add this header next to the others, adjusted for the services your app calls (for example your Supabase URL in connect-src):
Content-Security-Policy-Report-Only: default-src 'self'; connect-src 'self' https://YOUR-PROJECT.supabase.co; img-src 'self' data: https:; frame-ancestors 'none'Use the app normally for a day and watch the browser console for blocked requests. Add each source your app genuinely needs, then rename the header to Content-Security-Policy. Next.js apps that rely on inline scripts may need a nonce; the Next.js docs on Content Security Policy cover that setup.
6. Deploy and check again
Redeploy, run the curl command from step 1 again, and confirm each header shows up on your custom domain, not just the preview URL.
A prompt you can paste into your AI
Add security headers to this app for every route: Strict-Transport-Security, X-Content-Type-Options nosniff, X-Frame-Options DENY, Referrer-Policy strict-origin-when-cross-origin, and a Permissions-Policy that disables camera, microphone and geolocation. Use the config file that matches how this app is hosted (next.config.js, vercel.json or a Netlify _headers file). Do not add a Content-Security-Policy yet. Show me the diff.Quick answers
Which security headers should every app have?
Start with Strict-Transport-Security, X-Content-Type-Options: nosniff, a Referrer-Policy, a Permissions-Policy and protection against framing (X-Frame-Options or the CSP frame-ancestors directive). Add a Content-Security-Policy once you know which scripts and domains your app loads.
Will adding a Content-Security-Policy break my app?
It can, because a strict policy blocks scripts, styles and API calls from domains it does not list. Roll it out as Content-Security-Policy-Report-Only first, watch the browser console for blocked items, add what your app really needs, then switch to the enforcing header.
Do Lovable, Bolt or v0 add these headers for me?
Not reliably. It depends on where the app is hosted and how it was set up. Check the live site instead of assuming: open DevTools, go to the Network tab, click the first document request and read its response headers.
Are missing headers a serious vulnerability?
Usually they are hardening, not an open door. They limit the damage from other bugs such as cross-site scripting or clickjacking. Fix leaked keys and open database tables first, then add headers, which take only a few minutes.
How does Cheqvo check this?
A live-site scan requests your homepage like a normal visitor and reports which common security headers are missing, alongside checks for keys shipped in your JavaScript and readable Supabase tables. It is read-only.
Check your app now, free
Paste a GitHub repo or your live app's URL. You get a free score in under a minute, with no signup. The $19 Full Report gives a copy-paste AI fix for each issue found, and you get a full refund if the scan fails.
No signup · read-only · we never keep your code. How we handle your code
No signup. We only read. We never run your code or attack your site. We never keep your code, only your report. Reports are saved so you can track progress over time. Delete anytime on request. See the leaderboard
General guidance. A fast automated check for the most common security mistakes in AI-built apps. Not a substitute for a full security audit. Updated 2026-10-26.
All guides · Home · Terms · Privacy