import type { NextConfig } from "next"; const nextConfig: NextConfig = { /** * Cache-Control policy. * * Why this exists: * Hostinger's CDN was applying `s-maxage=31536000` (1 year) to * prerendered HTML pages by default. When a new deploy shipped * fresh Turbopack chunk hashes, the edge kept serving year-old * HTML referencing chunk filenames that no longer existed on * disk — result: HTML 200, every /_next/static/*.js and .css * came back 404, the page rendered unstyled. Private/incognito * did nothing because the cache is server-side. * * Strategy: * - /_next/static/* — immutable for a year. Filenames are * content-hashed, so a new build produces new filenames; the * old ones are safe to keep indefinitely in caches. * - /api/* — no-store. API responses are per-user and * must never be shared across requests at the edge. * - Everything else — public, brief s-maxage + generous * stale-while-revalidate. The edge serves instantly from cache * for the first 5 min, then returns cached content while * refreshing in the background for up to 24 h. A deploy's * chunk-hash drift self-heals within ~5 min with no user- * visible latency. * * Note: dynamic dashboard routes (/inbox, /contacts, /pipelines, * /broadcasts, etc.) are server-rendered per request — Next.js * and Supabase auth already prevent them from being served * from a shared cache. The s-maxage here is a ceiling; Next.js * and auth middleware still set `private` / `no-store` for * per-user responses. */ async headers() { return [ { source: "/_next/static/:path*", headers: [ { key: "Cache-Control", value: "public, max-age=31536000, immutable", }, ], }, { source: "/api/:path*", headers: [{ key: "Cache-Control", value: "no-store" }], }, { source: "/:path*", headers: [ { key: "Cache-Control", value: "public, max-age=0, s-maxage=300, stale-while-revalidate=86400", }, ], }, ]; }, }; export default nextConfig;