Skip to content

fix(site): version stylesheet and script URLs so deploys reach returning visitors - #69

Merged
etienne0101 merged 1 commit into
mainfrom
fix/asset-cache-busting/2026-11-04
Nov 5, 2026
Merged

etienne0101 merged 1 commit into
mainfrom
fix/asset-cache-busting/2026-11-04

Conversation

@etienne0101

Copy link
Copy Markdown
Contributor

Problem

After #68 was deployed, the History section on the specification pages showed only its fallback text ("Changes to this entry are reviewed on GitHub...") for anyone who had visited the site before.

Cause: the server lets browsers keep CSS and JS files for 4 hours (cache-control: max-age=14400), and the site's own files keep the same name from one deploy to the next. A returning visitor got the new HTML but reused the old specifications.js, which predates the History section. A browser with an empty cache showed the section correctly. Every future change to a stylesheet or script would hit the same problem.

Fix

A new hook, hooks/asset_versions.py, links each local entry of extra_css and extra_javascript with a version taken from the file's content:

assets/javascript/specifications.js?v=4f9819e1de
assets/stylesheets/specifications.css?v=4b2cd54e9c
  • The suffix is the first 10 hex digits of the file's SHA-256, so it changes only when the file does. Browsers keep their copy between deploys and fetch the new one as soon as it changes.
  • External URLs (Mermaid, Font Awesome) are left alone. Material's own bundle already has a hash in its file name.
  • Nothing changes for visitors: the same file is served with or without the suffix, and the suffix only appears in the page source.

Testing

  • Built with ProperDocs 1.6.7 (the production tool) in a clean environment: every page, root and nested, links the versioned URLs.
  • Served locally: on the GBFS page the CSS and script load from the versioned URLs, js-yaml is still found next to the script, and the History section renders its entries and tables.

Note

.claude/launch.json still points to config/en/mkdocs.yml, which was renamed to properdocs.yml in 267a022, so the local preview entries no longer start. Not changed here.

🤖 Generated with Claude Code

…ing visitors

The server lets browsers keep CSS and JS files for 4 hours
(cache-control: max-age=14400), and the site's own files keep the same name
from one deploy to the next. After a deploy a returning visitor gets the new
HTML with the old script or stylesheet. This is why the History section of
the specification pages stayed on its fallback text after #68 was deployed:
the cached specifications.js predated it.

A new hook, hooks/asset_versions.py, links every local entry of extra_css and
extra_javascript as <path>?v=<first 10 hex digits of the file's SHA-256>.
The suffix only changes when the file does, so browsers keep their copy
between deploys and fetch the new one as soon as it changes. External URLs
are left alone, and Material's own bundle already has a hash in its name.
Nothing changes for visitors: the same file is served with or without the
suffix.

Checked with ProperDocs 1.6.7: every page links e.g.
assets/javascript/specifications.js?v=4f9819e1de, and the GBFS page still
loads its History section and js-yaml.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@etienne0101
etienne0101 requested a review from carlfredl November 4, 2026 17:27
@etienne0101
etienne0101 merged commit 8708363 into main Nov 5, 2026
@etienne0101
etienne0101 deleted the fix/asset-cache-busting/2026-11-04 branch November 5, 2026 18:25
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.

2 participants