Skip to content

Always send a fresh index.html, so a deploy can't leave a blank page - #686

Open
lgelauff wants to merge 1 commit into
masterfrom
fix/index-html-no-cache-643
Open

lgelauff wants to merge 1 commit into
masterfrom
fix/index-html-no-cache-643

Conversation

@lgelauff

Copy link
Copy Markdown
Collaborator

Fixes #643.

index.html names the hashed JS and CSS bundles of the current build. It was served with Cache-Control: max-age=360 and Last-Modified: 1 Jan 1980 (the build gives every file that date), and clastic's StaticFileRoute answers a "changed since?" check by comparing with that date, so it said 304 every time. Browsers kept an old index.html that pointed at bundles the deploy had removed: a blank page until a hard refresh. The ETag middleware didn't help, because it skips streamed file responses.

/ and /a/ are now served by a small IndexFileRoute: cache_timeout=0, so clastic skips the date check and sends the file (about 1 KB), plus Cache-Control: no-cache. The hashed bundles under /assets/ are unchanged and stay cacheable. The frontend uses hash routing, so every app page loads through /.

A browser that already holds a stale copy gets the new page on its next normal reload, once this is deployed.

Tests

  • New test_index_html_is_never_stale: / and /a/ with an If-Modified-Since in the future answer 200 with the page and no-cache. It fails on master with 304.
  • Full suite: 172 passed, 3 xfailed.
  • On montage-dev with this branch deployed, Claude was able to check with curl: / and /a/ answer Cache-Control: max-age=0, no-cache, and a request with If-Modified-Since in 2100 gets 200 with the page (before: max-age=360 and 304). The bundles under /assets/ still have max-age=360.
  • Not tested: a browser reload after a second deploy.

Written by Claude (Claude Code) on behalf of @lgelauff.

🤖 Generated with Claude Code

index.html names the hashed JS/CSS bundles of the current build. It was
served with Cache-Control: max-age=360 and Last-Modified 1980 (the build
gives every file that time), and clastic answered every "changed since?"
check with 304. Browsers kept an old index.html that pointed at bundles a
deploy had removed, so coordinators and jurors got a blank page until they
hard-refreshed.

Serve / and /a/ through IndexFileRoute: cache_timeout=0, so clastic skips
the modification-time check and sends the file, plus Cache-Control:
no-cache. The hashed bundles stay cacheable. Browsers that hold a stale
copy get the new page on their next normal reload.

Adds a test (304 before the fix).

Fixes #643.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.

Stale index.html after a deploy leaves coordinators with a blank page

1 participant