From b6471f94308e88c6536ce528a0a8484b475fb61c Mon Sep 17 00:00:00 2001 From: gosangam Date: Thu, 2 Jul 2026 21:52:35 +0530 Subject: [PATCH] fix: offline content for iOS --- public/sw.js | 45 ++++++++++++++++++++++++++++----------------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/public/sw.js b/public/sw.js index f5b275f2..37cc7da2 100644 --- a/public/sw.js +++ b/public/sw.js @@ -48,25 +48,28 @@ self.addEventListener("fetch", (event) => { const url = new URL(req.url); - // 1. Page navigations: network-first, fall back to a saved copy, then to the - // offline library. This is what makes a "saved" page open with no network. + // 1. Page navigations. + // ONLINE: do NOT intercept — let the browser navigate natively. Proxying + // a redirected response (the app server-`redirect()`s every book chapter + // index to its first verse) or Next's streamed SSR through the SW makes + // iOS/WebKit standalone PWAs render a blank page. Native handling is + // identical to how the app behaved before this SW had a fetch handler. + // OFFLINE: serve a saved copy, then the offline library, then a stub — + // all plain stored/constructed Responses, which WebKit accepts. if (req.mode === "navigate") { + if (self.navigator.onLine) return; event.respondWith( (async () => { - try { - return await fetch(req); - } catch { - const pages = await caches.open(PAGES_CACHE); - const saved = - (await pages.match(req.url)) || (await pages.match(url.pathname)); - if (saved) return saved; - const fallback = await pages.match(OFFLINE_FALLBACK); - if (fallback) return fallback; - return new Response( - "Offline

You're offline

This page hasn't been saved for offline use.

", - { headers: { "Content-Type": "text/html; charset=utf-8" }, status: 503 }, - ); - } + const pages = await caches.open(PAGES_CACHE); + const saved = + (await pages.match(req.url)) || (await pages.match(url.pathname)); + if (saved) return saved; + const fallback = await pages.match(OFFLINE_FALLBACK); + if (fallback) return fallback; + return new Response( + "Offline

You're offline

This page hasn't been saved for offline use.

", + { headers: { "Content-Type": "text/html; charset=utf-8" }, status: 503 }, + ); })(), ); return; @@ -80,7 +83,15 @@ self.addEventListener("fetch", (event) => { const hit = await cache.match(req); if (hit) return hit; const res = await fetch(req); - if (res && res.ok) cache.put(req, res.clone()); + // Only cache full, same-origin 200s. Guard put() so a 206/opaque/quota + // rejection can never fail the request (which could drop a JS chunk). + try { + if (res && res.status === 200 && res.type === "basic") { + await cache.put(req, res.clone()); + } + } catch { + /* serve the response uncached */ + } return res; })(), );