const putInCache = async (request, response) => { const cache = await caches.open("v1"); await cache.put(request, response); }; const cacheFirst = async ({ request, fallbackUrl }) => { const responseFromCache = await caches.match(request); if (responseFromCache) { return responseFromCache; } try { const responseFromNetwork = await fetch(request); // Cloning is needed because a response can only be consumed once. putInCache(request, responseFromNetwork.clone()); return responseFromNetwork; } catch (error) { const fallbackResponse = await caches.match(fallbackUrl); if (fallbackResponse) { return fallbackResponse; } return new Response("Network error happened", { status: 408, headers: { "Content-Type": "text/plain" }, }); } }; self.addEventListener("fetch", (event) => { const requestUrl = URL.parse(event.request.url); // We don't cache API requests if (!requestUrl.pathname.startsWith("/api")) { event.respondWith( cacheFirst({ request: event.request, fallbackUrl: "/index.html", }), ); } });