Fix HSTS on Vercel

Vercel does not set Strict-Transport-Security by default. Add it via vercel.json headers — this applies to all routes including API endpoints.

Scan your Vercel site for missing headers →

Step 1 — Add HSTS to vercel.json

Add a headers array to your vercel.json at the project root. Start with a short e to verify HTTPS works correctly before committing to a long duration.

{ "headers": [ { "source": "/(.*)", "headers": [ { "key": "Strict-Transport-Security", "value": "max-age=300" } ] } ] }

Deploy and verify the header appears in your response before increasing max-age.

Step 2 — Ramp up safely

Once you have confirmed HTTPS works correctly on all routes and subdomains, increase max-age to one year and add includeSubDomains:

{ "headers": [ { "source": "/(.*)", "headers": [ { "key": "Strict-Transport-Security", "value": "max-age=31536000; includeSubDomains" } ] } ] }

Only add includeSubDomains when every subdomain on your domain supports HTTPS. If any subdomain is HTTP-only, browsers will refuse to connect to it after the HSTS hear is cached.

Step 3 — Add preload (optional)

To submit your domain to the HSTS preload list built into browsers, add the preload directive. This enforces HTTPS on the very first visit — before the browser has seen any header from your server.

{ "headers": [ { "source": "/(.*)", "headers": [ { "key": "Strict-Transport-Security", "value": "max-age=31536000; includeSubDomains; preload" } ] } ] }

After deploying, submit your domain at hstspreload.org. Preload list inclusion takes 2-3 months to appear in browser releases.

Next.js — next.config.js alternative

For Next.js projects, you can set headers in next.config.js instead of vercel.json. Both approaches work — next.config.js takes precedence if both are prp>

// next.config.js const securityHeaders = [ { key: 'Strict-Transport-Security', value: 'max-age=31536000; includeSubDomains' } ] module.exports = { async headers() { return [ { source: '/(.*)', headers: securityHeaders, }, ] }, }

Verify your HSTS header

curl -sI https://your-vercel-app.vercel.app | grep -i strict

You should see strict-transport-security: max-age=31536000; includeSubDomains in the response. If the header is missing, check that your vercel.json is at the project root and has been deployed.