Files
kiosk-guestbook/static/sw.js
T
steve b20e118def feat: add offline queue for kiosk form submissions
Intercepts form submit via fetch and stores failed submissions in
IndexedDB when offline. Replays queued entries on the online event and
on each page load. Shows an offline banner on the form page and a
sync-pending message on the thank-you page.

Service worker bumped to guestbook-v2 to pre-cache offline-queue.js
so the script is available when the kiosk has no network.
2026-03-29 20:22:25 -06:00

51 lines
1.8 KiB
JavaScript

const CACHE_NAME = 'guestbook-v2';
const STATIC_ASSETS = [
'https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css',
'https://cdn.jsdelivr.net/npm/@popperjs/core@2.10.2/dist/umd/popper.min.js',
'https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js',
'https://fonts.googleapis.com/css2?family=Vollkorn:wght@700&family=Open+Sans&display=swap',
'/static/images/logo.png',
'/static/offline-queue.js',
];
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME)
.then(cache => cache.addAll(STATIC_ASSETS))
.then(() => self.skipWaiting())
);
});
self.addEventListener('activate', event => {
event.waitUntil(
caches.keys().then(keys =>
Promise.all(keys.filter(k => k !== CACHE_NAME).map(k => caches.delete(k)))
).then(() => self.clients.claim())
);
});
self.addEventListener('fetch', event => {
const url = new URL(event.request.url);
// Cache-first for CDN and local static assets
const isStatic = STATIC_ASSETS.includes(event.request.url) ||
(url.origin === self.location.origin && url.pathname.startsWith('/static/'));
if (isStatic) {
event.respondWith(
caches.match(event.request).then(cached => {
if (cached) return cached;
return fetch(event.request).then(response => {
const clone = response.clone();
caches.open(CACHE_NAME).then(cache => cache.put(event.request, clone));
return response;
});
})
);
return;
}
// Network-only for all app routes (/, /admin/*, /api/*, /manifest.webmanifest)
// No caching of authenticated or dynamic content
});