Root cause: Hostinger's CDN was applying s-maxage=31536000 (1 year)
to prerendered HTML pages by default. Each deploy produced fresh
Turbopack chunk hashes, but the edge kept serving year-old HTML that
referenced chunk filenames the new build no longer had on disk —
resulting in HTML 200 + every /_next/static/*.{js,css} 404, page
rendered unstyled. Private/incognito didn't help because the cache
is at the edge, not the browser.
Fix: explicit Cache-Control via next.config.ts headers():
- /_next/static/* — public, max-age=31536000, immutable
Content-hashed filenames; safe forever.
- /api/* — no-store
Per-user, must never be shared at the edge.
- everything else — public, max-age=0, s-maxage=300,
stale-while-revalidate=86400
Edge serves instantly from cache for 5 min, then keeps serving
cached content while refreshing in the background for up to 24h.
Chunk-hash drift after a deploy self-heals within ~5 min.
Verification after deploy:
curl -I https://<host>/login | grep -i cache-control
Expect: public, max-age=0, s-maxage=300, stale-while-revalidate=86400
(If Hostinger overwrites this, fall back to configuring
purge-on-deploy at the platform layer.)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>