fix: serve HTML with no-store so deploys aren't stale until a hard refresh - #48
Merged
Conversation
✅ Deploy Preview for pittcswiki ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
…fresh Pages were served as static HTML with a cacheable Cache-Control, so browsers kept showing an old build until a manual hard refresh (across all devices, independent of cookies). Next.js hardcodes a cacheable header on statically prerendered pages and ignores overrides from netlify.toml, next.config.js, and middleware, so the only reliable fix is dynamic rendering. - Force dynamic rendering in the root layout so every document is served with Cache-Control: no-store (Next.js emits this for dynamic routes). Hashed /_next/static assets keep their immutable cache. - Scope netlify.toml headers to reassert immutable caching for build assets instead of a no-op blanket rule on /*. - Fix the light-mode flash on the home page: drive the hero gradient from CSS keyed on the .dark class (set pre-paint) instead of React state that starts in light mode, removing the client-only hooks.
codingshreyash
force-pushed
the
fix/stale-html-cache
branch
from
August 2, 2026 23:06
791624c to
3908608
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The site kept opening with an old build and only showed the current version after a hard refresh — on every device, and unaffected by clearing cookies.
Root cause is HTTP caching of the HTML document (there is no service worker). The live CDN serves the new build, so the stale copy lives in each browser's local cache.
netlify.tomltried to sendno-store, but Next.js hardcodes a cacheableCache-Controlon statically-prerendered pages and overrides any header set vianetlify.toml,next.config.js, or middleware. The only reliable way to emitno-storeis dynamic rendering.Changes
app/layout.tsx—export const dynamic = "force-dynamic"in the root layout cascades to every route. Documents are now servedCache-Control: no-store, ...; hashed/_next/staticassets keeppublic, max-age=31536000, immutable.netlify.toml— replaced the ineffective, mis-scopedfor = "/*"block with a rule that only reasserts immutable caching for/_next/static/*.app/page.tsx+app/globals.css— fixed the light-mode flash: the hero gradient is now driven by CSS keyed on the.darkclass (set pre-paint) instead of React state that started in light mode. Removed the client-only hooks; the home page is now a server component.Verification
λ); lint clean; tests pass.next start): documents returnno-store, hashed assets stayimmutable.Tradeoff
Every page is now server-rendered per request instead of served as cached static HTML — slightly slower first byte and more Netlify function calls. Negligible for a wiki this size; it's the price of guaranteeing no page is ever stale.
Before merging
Confirm on the Netlify deploy preview that the header actually reaches the browser (Netlify is the final authority):