Stop caching index.html so deploys take effect immediately - #202
Merged
Conversation
nginx served index.html with no Cache-Control, so browsers heuristically cached it and kept loading the previous build's hashed bundle until a hard refresh. Mark index.html no-cache (always revalidate) and the content-hashed /assets/ immutable so new deploys are picked up on the next navigation without serving stale assets. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drive Cache-Control from a single server-level `add_header` backed by a $uri map, rather than per-location add_header blocks. Per-location add_header would suppress inheritance of any server-wide headers added later (e.g. security headers) — a common nginx footgun. The map keeps content-hashed /assets/ immutable and the SPA entry point no-cache, and emits no header for proxied API/editor responses. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Split out from #201.
nginx served
index.htmlwithETag/Last-Modifiedbut noCache-Control, so browsers heuristically cached it and kept loading the previous build's hashed bundle until a manual hard refresh (this is why a freshly deployed UI change didn't appear without one).index.html→Cache-Control: no-cache(always revalidate; cheap 304s via the existing ETag)./assets/(Vite content-hashed, immutable) →Cache-Control: public, max-age=31536000, immutable.New deploys are picked up on the next normal navigation, with no stale-asset risk.
Testing
nginx -tagainst the updated config: syntax OK.🤖 Generated with Claude Code
Greptile Summary
This PR fixes browser heuristic caching of
index.htmlthat prevented freshly deployed UI changes from appearing without a hard refresh. Amapdirective keyed on$uridrives a single server-leveladd_header Cache-Control $cache_control, routing Vite content-hashed assets topublic, max-age=31536000, immutableand the SPA entry point tono-cache.locationblock correctly avoids theadd_headerinheritance pitfall flagged on the previous attempt.default \"\") cause nginx to suppress the header entirely for proxied API/editor responses, which is the correct behavior.try_files $uri $uri/ /index.htmlfallback and theindex index.htmlresolution both perform an internal redirect that updates$urito/index.htmlbefore the response-filter phase, so theno-cachepolicy is applied to all SPA routes—not just literal/index.htmlrequests.Confidence Score: 5/5
Safe to merge — the change is a targeted nginx caching fix with no logic changes to the application code.
The map + server-level add_header approach is correct: empty values suppress the header for proxied routes, the /index.html pattern covers all SPA routes served via try_files/index rewrites, and assets get a proper immutable policy. No correctness issues found.
No files require special attention.
Important Files Changed
Reviews (2): Last reviewed commit: "Set SPA cache headers via a server-level..." | Re-trigger Greptile