4f8d0f44fb
Per internal#562 audit, HTML pages on docs.moleculesai.app respond with `Cache-Control: max-age=0, must-revalidate` while Vercel Edge is HITting them. That means a browser round-trip to the edge on every navigation just to get a 304 — no benefit from edge cache being warm. Adds a single `headers()` rule in next.config.mjs that sets `public, max-age=0, s-maxage=300, stale-while-revalidate=86400` on every path EXCEPT Next.js internals (/_next/static and /_next/image — already immutable and uncacheable-override per Next.js docs) and /api/* (app-controlled cache). The source pattern `/((?!_next/static|_next/image|api/).*)` uses path-to-regexp negative lookahead — same pattern Next.js's own proxy.js doc recommends for negative matching. This site has no /public/ dir so there are no unhashed brand assets to configure separately — those will inherit the same HTML cache rule, which is the right default for our content (changelog/docs MDX, not high-churn). Expected impact: edge-HIT ratio on HTML pages rises from ~0% to >90% during typical nav bursts (5 min freshness) and 99%+ for repeat visits within 24 h (stale-while-revalidate window). Hashed _next/static assets retain their `immutable, max-age=31536000` headers — Next.js sets these and they cannot be overridden in next.config. RFC: internal#562 (step 1 — Vercel side; CF cache rules tracked separately)
35 lines
1.1 KiB
JavaScript
35 lines
1.1 KiB
JavaScript
import { createMDX } from 'fumadocs-mdx/next';
|
|
|
|
const withMDX = createMDX();
|
|
|
|
// HTML pages: short edge cache + long stale-while-revalidate. Lets Vercel Edge
|
|
// serve repeat navigations from cache (~5 min fresh, 24 h stale-while-revalidate
|
|
// in the background) while keeping the browser revalidating on every nav. The
|
|
// negative lookahead leaves Next.js's own _next/static (immutable, hash-named)
|
|
// and _next/image cache headers untouched.
|
|
const HTML_CACHE_CONTROL =
|
|
'public, max-age=0, s-maxage=300, stale-while-revalidate=86400';
|
|
|
|
/** @type {import('next').NextConfig} */
|
|
const config = {
|
|
reactStrictMode: true,
|
|
async headers() {
|
|
return [
|
|
{
|
|
// Match every path except Next.js internals and API routes — those
|
|
// already have correct cache headers (immutable for hashed assets,
|
|
// app-controlled for /api).
|
|
source: '/((?!_next/static|_next/image|api/).*)',
|
|
headers: [
|
|
{
|
|
key: 'Cache-Control',
|
|
value: HTML_CACHE_CONTROL,
|
|
},
|
|
],
|
|
},
|
|
];
|
|
},
|
|
};
|
|
|
|
export default withMDX(config);
|