From 2847ec19cd1e92183a5dbadfda37c9318fed7809 Mon Sep 17 00:00:00 2001 From: Noley Holland Date: Tue, 8 Sep 2026 10:31:26 -0700 Subject: [PATCH 1/2] Add navigationRoute that allows for auth redirects with offline fallback --- ui/src/sw.js | 41 +++++++++++++++++++---------------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/ui/src/sw.js b/ui/src/sw.js index 2096874cd..4b8de49f2 100644 --- a/ui/src/sw.js +++ b/ui/src/sw.js @@ -1,34 +1,31 @@ /// import { clientsClaim } from 'workbox-core' -import { cleanupOutdatedCaches, createHandlerBoundToURL, precacheAndRoute } from 'workbox-precaching' +import { cleanupOutdatedCaches, matchPrecache, precacheAndRoute } from 'workbox-precaching' import { NavigationRoute, registerRoute } from 'workbox-routing' -// self.__WB_MANIFEST is the default injection point -precacheAndRoute(self.__WB_MANIFEST) +// directoryIndex/cleanURLs off so the precache doesn't serve a /dashboard/ navigation from cache - the route below owns navigations +precacheAndRoute(self.__WB_MANIFEST, { + directoryIndex: null, + cleanURLs: false +}) // clean old assets cleanupOutdatedCaches() -/** @type {RegExp[] | undefined} */ -const denylist = [] +const NETWORK_TIMEOUT_MS = 5000 -// in dev mode, do not precache anything -if (import.meta.env.DEV) { - // don't precache anything - console.log('Development mode, not pre-caching anything') - denylist.push(/.*/) -} else { - // don't precache anything where the urls pathname ends with a slash (including times when the url has a query string) - // this permits the request to be handled by the server which will do a redirect as required - const configPath = self.location.pathname.split('/')[1] - denylist.push(new RegExp(`/${configPath}/[^?]*/(\\?.*)*$`)) -} - -// to allow work offline for allowed routes only -registerRoute(new NavigationRoute( - createHandlerBoundToURL('index.html'), - { denylist } -)) +// Network-first so an auth proxy's login redirect is followed - cached shell as offline fallback +registerRoute(new NavigationRoute(async ({ request }) => { + const controller = new AbortController() + const timeout = setTimeout(() => controller.abort(), NETWORK_TIMEOUT_MS) + try { + return await fetch(request, { signal: controller.signal }) + } catch { + return (await matchPrecache('index.html')) || Response.error() + } finally { + clearTimeout(timeout) + } +})) self.skipWaiting() // https://developer.mozilla.org/en-US/docs/Web/API/Clients/claim From dfa3000e5d7f9ea1c8c5c5f3b65d84875edd5fb9 Mon Sep 17 00:00:00 2001 From: Noley Holland Date: Tue, 8 Sep 2026 11:12:22 -0700 Subject: [PATCH 2/2] Skip precaching in dev builds so the service worker doesn't serve stale assets during local development --- vite.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vite.config.js b/vite.config.js index e0ce35fc0..0e2d94816 100644 --- a/vite.config.js +++ b/vite.config.js @@ -32,7 +32,7 @@ export default defineConfig({ injectManifest: { maximumFileSizeToCacheInBytes: process.env.NODE_ENV === 'development' ? 6000000 : 3350000, - globPatterns: ['**/*.{js,css,html,svg,png,ico,ttf,eot,woff,woff2}'] + globPatterns: process.env.NODE_ENV === 'development' ? [] : ['**/*.{js,css,html,svg,png,ico,ttf,eot,woff,woff2}'] }, devOptions: {