const CACHE_NAME = "apicore-shell-v2"; self.addEventListener("install", () => { self.skipWaiting(); }); self.addEventListener("activate", (event) => { event.waitUntil( caches .keys() .then((keys) => Promise.all(keys.filter((key) => key !== CACHE_NAME).map((key) => caches.delete(key))), ) .then(() => self.clients.claim()), ); }); self.addEventListener("fetch", (event) => { const { request } = event; if (request.method !== "GET") { return; } const url = new URL(request.url); if (url.origin !== self.location.origin || url.pathname.startsWith("/api")) { return; } // Page navigations must never be answered with a synthetic Response.error() - // Chrome/Edge render that as a native "This page couldn't load" interstitial // instead of the app. Let the browser handle navigations directly; only // static assets (JS/CSS/images) go through the offline-cache fallback below. if (request.mode === "navigate") { return; } event.respondWith( fetch(request) .then((response) => { const responseClone = response.clone(); return caches .open(CACHE_NAME) .then((cache) => cache.put(request, responseClone)) .then(() => response); }) .catch(() => caches.match(request).then((cached) => cached || Response.error())), ); });