Skip to content

Stop caching index.html so deploys take effect immediately - #202

Merged
skearnes merged 2 commits into
mainfrom
fix/spa-cache-headers
Jun 25, 2026
Merged

Stop caching index.html so deploys take effect immediately#202
skearnes merged 2 commits into
mainfrom
fix/spa-cache-headers

Conversation

@skearnes

@skearnes skearnes commented Jun 25, 2026

Copy link
Copy Markdown
Member

Split out from #201.

nginx served index.html with ETag/Last-Modified but no Cache-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.htmlCache-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 -t against the updated config: syntax OK.

🤖 Generated with Claude Code

Greptile Summary

This PR fixes browser heuristic caching of index.html that prevented freshly deployed UI changes from appearing without a hard refresh. A map directive keyed on $uri drives a single server-level add_header Cache-Control $cache_control, routing Vite content-hashed assets to public, max-age=31536000, immutable and the SPA entry point to no-cache.

  • Placing the directive at the server block rather than duplicating it in every location block correctly avoids the add_header inheritance pitfall flagged on the previous attempt.
  • Empty string values in the map (default \"\") cause nginx to suppress the header entirely for proxied API/editor responses, which is the correct behavior.
  • The try_files $uri $uri/ /index.html fallback and the index index.html resolution both perform an internal redirect that updates $uri to /index.html before the response-filter phase, so the no-cache policy is applied to all SPA routes—not just literal /index.html requests.

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

Filename Overview
ord_interface/nginx.conf Adds a map-based Cache-Control policy: no-cache for index.html, immutable for /assets/, and no header for API/editor routes; header is set once at the server level to avoid add_header inheritance surprises.

Reviews (2): Last reviewed commit: "Set SPA cache headers via a server-level..." | Re-trigger Greptile

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>
Comment thread ord_interface/nginx.conf Outdated
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>
@skearnes
skearnes merged commit e6aea88 into main Jun 25, 2026
16 checks passed
@skearnes
skearnes deleted the fix/spa-cache-headers branch June 25, 2026 01:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant