From aa7cf061e69ec1c068cd0ae32983b287ae536946 Mon Sep 17 00:00:00 2001 From: Pierre-Olivier Mercier Date: Wed, 18 Feb 2026 18:16:17 +0700 Subject: [PATCH] web: fix service worker caching bugs - Add network fallback for asset cache misses (prevents broken requests on install race conditions) - Fix query string stripping to use a clean Request instead of copying event.request options - Await cache.put() calls to prevent incomplete writes on SW termination - Expand auth path exclusion to startsWith("/api/auth") to cover all auth-related endpoints --- web/src/service-worker.ts | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/web/src/service-worker.ts b/web/src/service-worker.ts index 89cfeda2..cb8ffea2 100644 --- a/web/src/service-worker.ts +++ b/web/src/service-worker.ts @@ -53,11 +53,16 @@ self.addEventListener('fetch', (event) => { // `build`/`files` can always be served from the cache if (ASSETS.includes(url.pathname)) { - if (url.search.length) { - url.search = ""; - return cache.match(new Request(url.toString(), event.request)); + // Strip query string for asset cache lookup (assets are keyed by pathname only) + const cacheKey = url.search.length + ? new Request(url.origin + url.pathname) + : event.request; + const responseFromCache = await cache.match(cacheKey); + if (responseFromCache) { + return responseFromCache; } - return cache.match(event.request); + // Fall back to network if not yet in cache (e.g. install race condition) + return fetch(event.request); } if ( @@ -72,7 +77,7 @@ self.addEventListener('fetch', (event) => { const response = await fetch(event.request); if (response.status === 200) { - cache.put(event.request, response.clone()); + await cache.put(event.request, response.clone()); } return response; @@ -83,8 +88,8 @@ self.addEventListener('fetch', (event) => { try { const response = await fetch(event.request); - if (response.status === 200 && url.pathname != "/api/auth") { - cache.put(event.request, response.clone()); + if (response.status === 200 && !url.pathname.startsWith("/api/auth")) { + await cache.put(event.request, response.clone()); } return response;