SW: cache navigation response offline (v9)
All checks were successful
Build and push Docker image / build (push) Successful in 14s
Test / test (push) Successful in 14s

Ohne diesen Fix schlägt das Öffnen der App im Flugzeug fehl, weil der
Service Worker die HTML-Seite (/) nicht cached — der Browser zeigt
dann eine Netzwerkfehler-Seite bevor JS überhaupt startet.

Strategie: Network-first für Navigationsanfragen, bei Netzwerkfehler
die zuletzt gecachte Version ausliefern. Nach dem ersten Online-Besuch
funktioniert die App vollständig offline.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
marwin 2026-05-29 23:58:07 +02:00
parent 5ba1a7bdad
commit a96591c63f

View file

@ -2,7 +2,7 @@
* diora service worker caches the app shell for offline use. * diora service worker caches the app shell for offline use.
*/ */
const CACHE = 'diora-v8'; const CACHE = 'diora-v9';
const PODCAST_CACHE = 'diora-podcast-v1'; const PODCAST_CACHE = 'diora-podcast-v1';
const SHELL = [ const SHELL = [
'/static/css/app.css', '/static/css/app.css',
@ -71,7 +71,7 @@ self.addEventListener('fetch', function (event) {
return; return;
} }
// Cache-first only for pre-defined shell assets; everything else hits the network // Cache-first for pre-defined shell assets
const isShell = SHELL.some(function (s) { return url.pathname === s; }); const isShell = SHELL.some(function (s) { return url.pathname === s; });
if (isShell) { if (isShell) {
event.respondWith( event.respondWith(
@ -79,5 +79,22 @@ self.addEventListener('fetch', function (event) {
return cached || fetch(event.request); return cached || fetch(event.request);
}) })
); );
return;
}
// Navigation requests (the HTML page itself): network-first, fall back to
// last cached version so the app opens offline after being visited once.
if (event.request.mode === 'navigate') {
event.respondWith(
fetch(event.request).then(function (response) {
if (response.ok) {
var clone = response.clone();
caches.open(CACHE).then(function (cache) { cache.put(event.request, clone); });
}
return response;
}).catch(function () {
return caches.match(event.request);
})
);
} }
}); });