fix(web): mark static assets no-cache to stop CDN version skew - #108
Merged
Merged
Conversation
app.js and index.html live at fixed, unhashed paths and every deploy overwrites them in place. On tl.reccd.stream, Cloudflare cached app.js at the edge for hours while index.html (no explicit header) was always DYNAMIC, so a deploy could leave a fresh index.html paired with a stale cached app.js until the CDN's TTL expired — reproduced as two different cached copies of /app.js served simultaneously, one of them wired for a DOM shape the served HTML no longer matched, which threw Cannot read properties of null (reading 'addEventListener') on load. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MPpJwadYAkvKmYvDuMwg6n
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.
Summary
tl.reccd.streamwas throwingCannot read properties of null (reading 'addEventListener')atapp.ts:2152on load. Cloudflare was caching/app.jsat the edge for hours (confirmed two different cached copies of/app.jsserved simultaneously,Age: 4048vsAge: 112) whileindex.htmlwas always fetched fresh (DYNAMIC), since neither response carried aCache-Controlheader from the origin.index.htmlwith a stale cachedapp.jswhose listeners expect an older DOM shape, until the CDN's default TTL expires.src/web/server.tsnow sendsCache-Control: no-cacheon every static asset served (index.html, player.html, app.js/player.js/chunks, styles.css, fonts), forcing revalidation on each request instead of letting a downstream cache reuse a stale copy.Test plan
npm test(3310 passed, including a new regression test assertingCache-Control: no-cacheon/and/app.js)npm run typechecknpm run lint(only the known pre-existingreact-hooks/exhaustive-depswarning)npm run buildtl.reccd.streamand confirmed the root cause (two differently-sized cached/app.jsresponses) before fixingNote: this needs a deploy to take effect on
tl.reccd.stream, and since Cloudflare currently has a staleapp.jscached there, purging its cache after deploying will make the fix effective immediately rather than waiting out the existing TTL.🤖 Generated with Claude Code
https://claude.ai/code/session_01MPpJwadYAkvKmYvDuMwg6n