From fcccb1751d91143c9fea01d650f74b797b877521 Mon Sep 17 00:00:00 2001 From: Tom Cobb Date: Fri, 19 Jun 2026 13:55:36 +0000 Subject: [PATCH] version-switcher: fetch switcher.json fresh (bypass cache) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit switcher.json changes every deploy, but GitHub Pages serves it with Cache-Control: max-age=600, so the dropdown could show a version list up to ~10 min stale (a new pr-/release wouldn't appear without a hard reload). Bust both layers: a unique query string forces a CDN-edge miss → origin, and cache: "no-store" stops the browser serving its own copy. The file is tiny, so always-fresh is cheap. Co-Authored-By: Claude Opus 4.8 --- plugins/version-switcher.mjs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/plugins/version-switcher.mjs b/plugins/version-switcher.mjs index 4e8542b..1660cdc 100644 --- a/plugins/version-switcher.mjs +++ b/plugins/version-switcher.mjs @@ -374,8 +374,18 @@ export async function render({ model, el }) { } try { - const resolved = new URL(jsonUrl, window.location.href).href; - const res = await fetch(resolved, { credentials: "omit" }); + // switcher.json changes every deploy (a new version, a closed PR), and + // GitHub Pages serves it with Cache-Control: max-age=600, so a plain fetch + // can show a list that's up to ~10 min stale. Bust both caches: a unique + // query string forces a CDN-edge miss (→ origin), and `no-store` stops the + // browser serving its own cached copy. switcher.json is tiny, so always + // fetching fresh is cheap and keeps the dropdown current. + const resolved = new URL(jsonUrl, window.location.href); + resolved.searchParams.set("_", Date.now().toString()); + const res = await fetch(resolved.href, { + credentials: "omit", + cache: "no-store", + }); if (!res.ok) throw new Error(`HTTP ${res.status}`); const raw = await res.json();