diff --git a/tools/build_static.py b/tools/build_static.py index 3888cdf..89cb1c6 100644 --- a/tools/build_static.py +++ b/tools/build_static.py @@ -70,18 +70,20 @@ def _write_redirects(out: Path, seg: str) -> None: def _write_headers(out: Path, seg: str) -> None: # The app shell must NOT be browser-cached — otherwise a deploy is invisible to - # returning visitors for hours (Pages' default is max-age=14400). The HTML entry - # points get `no-store` (never stored → a guaranteed-fresh index every visit): - # `no-cache` (revalidate) was not enough — Safari served a STALE index from its - # disk/bfcache, which then loaded the OLD versioned JS and broke the page. A fresh - # index is the linchpin: it carries the content-hashed asset URLs (see - # _version_assets), so once the HTML is fresh the JS/CSS are too. The rest of the - # app path stays `no-cache`. Media is on R2 (immutable + content-hash), unaffected. - # Cloudflare Pages `_headers` syntax; later rules win for the same header. - html_pages = ("", "index.html", "credits.html", "about.html") # "" = the /seg/ root - blocks = [f"/{seg}/*\n Cache-Control: no-cache\n"] - blocks += [f"/{seg}/{p}\n Cache-Control: no-store\n" for p in html_pages] - (out / "_headers").write_text("".join(blocks)) + # returning visitors for hours (Pages' default is max-age=14400). `no-store` + # (never stored → a guaranteed-fresh fetch every visit) for the whole app path: + # `no-cache` (revalidate) was NOT enough — Safari served a STALE index from its + # disk/bfcache, loaded the OLD versioned JS, and broke the page (black, silent). + # A per-HTML no-store override didn't stick (Pages let the `/seg/*` rule win), so + # we no-store the whole path. The app shell is tiny (~150 KB); the media is on R2 + # (immutable + content-hash, a separate domain) and is unaffected. The content- + # hashed asset URLs (see _version_assets) remain as belt-and-suspenders for the + # case where Pages caches .js/.css at the edge by type and ignores _headers. + # Cloudflare Pages `_headers` syntax. + (out / "_headers").write_text( + f"/{seg}/*\n" + " Cache-Control: no-store\n" + ) def _version_assets(app_dir: Path) -> None: