Fix Cache-Control Headers on Vercel
Last updated: April 2026
Vercel sets sensible defaults but you may need to override them for API routes, static assets, or HTML pages. Set Cache-Control headers in vercel.json or next.config.js.
vercel.json โ cache headers by route pattern
{
"headers": [
{
"source": "/api/(.*)",
"headers": [
{ "key": "Cache-Control", "value": "no-store" }
]
},
{
"source": "/_next/static/(.*)",
"headers": [
{ "key": "Cache-Control", "value": "public, max-age=31536000, immutable" }
]
},
{
"source": "/(.*)\.html",
"headers": [
{ "key": "Cache-Control", "value": "no-cache" }
]
}
]
}
Next.js โ next.config.js headers
module.exports = {
async headers() {
return [
{
source: '/api/:path*',
headers: [{ key: 'Cache-Control', value: 'no-store' }],
},
{
source: '/_next/static/:path*',
headers: [{ key: 'Cache-Control', value: 'public, max-age=31536000, immutable' }],
},
];
},
};
Next.js App Router โ route handler cache config
// app/api/data/route.ts
export const revalidate = 60; // ISR โ revalidate every 60 seconds
export async function GET() {
const data = await fetchData();
return Response.json(data, {
headers: {
'Cache-Control': 'public, max-age=60, stale-while-revalidate=300',
},
});
}
Vercel Edge Config โ stale-while-revalidate
{
"headers": [
{
"source": "/api/public/(.*)",
"headers": [
{
"key": "Cache-Control",
"value": "public, max-age=60, stale-while-revalidate=300"
}
]
}
]
}
Verify your cache headers
curl -sI https://yourapp.vercel.app/api/data | grep -i cache-control curl -sI https://yourapp.vercel.app/_next/static/chunks/main.js | grep -i cache-control