Security headers tell browsers to always use HTTPS, refuse to sniff file types, and block your pages from being framed by other sites. Netlify doesn't add most of these for you, but you can set them for every page with a few lines of config.
Create a file named _headers (no extension) in your site's publish directory, the folder Netlify deploys, such as public or dist:
/* Strict-Transport-Security: max-age=31536000; includeSubDomains X-Content-Type-Options: nosniff X-Frame-Options: DENY Referrer-Policy: strict-origin-when-cross-origin Permissions-Policy: camera=(), microphone=(), geolocation=()
The first line is the path pattern and each header goes on its own indented line below it.
If you already use netlify.toml in your repo root, add this instead:
[[headers]]
for = "/*"
[headers.values]
Strict-Transport-Security = "max-age=31536000; includeSubDomains"
X-Content-Type-Options = "nosniff"
X-Frame-Options = "DENY"
Referrer-Policy = "strict-origin-when-cross-origin"
Permissions-Policy = "camera=(), microphone=(), geolocation=()"Use one method or the other for a given header so you don't end up with conflicting values. Commit and deploy.
curl -sI https://yourdomain.com | grep -iE "strict-transport|x-frame|x-content|referrer|permissions"
Each header should appear in the response. Note that headers set this way apply to static files Netlify serves; responses from Netlify Functions need the headers set in the function's own response.
includeSubDomains; browsers will refuse plain HTTP for a full year once they see it.max-age=300, confirm nothing breaks, then raise it to 31536000.preload and submit to hstspreload.org when you're sure, because removal from the preload list takes months.X-Frame-Options: SAMEORIGIN or a frame-ancestors Content-Security-Policy instead of DENY.Not sure what your site is missing? Run a free SiteShield scan to check your email authentication, HTTPS, and security headers in under a minute.
SiteShield by Telekeen · Telekeen Communications