commit 1cec7f3186be84cbf11de7d9e942386003c71e22
parent 82fafda9c0ea62e01d81a0c8c49b007dd000c05a
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date: Sat, 26 Sep 2026 18:22:51 -0400
export: both service workers cache /kofi-symbol.svg like the icons
The footer's Ko-fi mark is a static file of its own, outside /icons/, so it
fell through both workers to the network: an installed app opened offline
drew an empty link where the mark should be. It now takes the icons' rule,
network-first into shell-v2. No cache renamed, nothing evicted.
serviceWorkerRouting.test.ts: +1 per worker (online stored, offline
served); it fails with the site worker's old condition.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Diffstat:
3 files changed, 19 insertions(+), 3 deletions(-)
diff --git a/common/lib/archive/serviceWorkerRouting.test.ts b/common/lib/archive/serviceWorkerRouting.test.ts
@@ -129,6 +129,17 @@ for (const file of ["export/service-worker/site-sw.js", "export/service-worker/s
assert.equal(sw.cached("shell-v2", "/icons/icon.svg"), undefined);
});
+ test(`${file}: the footer's /kofi-symbol.svg is network-first in shell-v2 — an installed app draws it offline`, async () => {
+ // Not under /icons/: it is a static file of its own, on every page's
+ // footer. Without its own rule it fell through to the network, so an
+ // offline launch drew an empty link where the mark should be.
+ const sw = loadWorker(file);
+ assert.equal(await sw.request("/kofi-symbol.svg", { online: true, network: "mark" }), "mark");
+ assert.deepEqual(sw.fetched, ["/kofi-symbol.svg"]);
+ assert.equal(sw.cached("shell-v2", "/kofi-symbol.svg"), "mark");
+ assert.equal(await sw.request("/kofi-symbol.svg", { online: false }), "mark");
+ });
+
test(`${file}: /_next/static/ stays cache-first`, async () => {
const sw = loadWorker(file);
sw.seed("shell-v2", "/_next/static/chunks/app.js", "cached chunk");
diff --git a/export/service-worker/site-sw.js b/export/service-worker/site-sw.js
@@ -8,7 +8,8 @@
* Caches:
* SHELL — app shell: hashed /_next/static/* (immutable, cache-first) + HTML
* navigations (network-first, cache fallback) + /icons/* (network-
- * first: they follow the site's accent, which a redeploy can change).
+ * first: they follow the site's accent, which a redeploy can change)
+ * + the footer's /kofi-symbol.svg (network-first, the same rule).
* PAGES — every published JSON document: the per-channel shard trees
* (manifest.json + page-NNNN.json), the site-wide flat trees
* (summaries, stats) and the root documents (corpus.json, site.json,
@@ -104,7 +105,9 @@ self.addEventListener("fetch", (event) => {
event.respondWith(cacheFirst(req, SHELL));
return;
}
- if (url.pathname.startsWith("/icons/")) {
+ // The footer's Ko-fi mark is a static file of its own (/kofi-symbol.svg,
+ // on every page): the same rule, so an installed app still draws it offline.
+ if (url.pathname.startsWith("/icons/") || url.pathname === "/kofi-symbol.svg") {
event.respondWith(networkFirst(req, SHELL));
return;
}
diff --git a/export/service-worker/sw-hub.js b/export/service-worker/sw-hub.js
@@ -94,7 +94,9 @@ self.addEventListener("fetch", (event) => {
event.respondWith(cacheFirst(req, SHELL));
return;
}
- if (url.pathname.startsWith("/icons/")) {
+ // The footer's Ko-fi mark is a static file of its own (/kofi-symbol.svg,
+ // on every page): the same rule, so an installed app still draws it offline.
+ if (url.pathname.startsWith("/icons/") || url.pathname === "/kofi-symbol.svg") {
event.respondWith(networkFirst(req, SHELL));
return;
}