Skip to content

Instantly share code, notes, and snippets.

@jpawlyn
Created March 9, 2025 06:28
Show Gist options
  • Select an option

  • Save jpawlyn/21add7c5cad7a8edfa911457b2f63830 to your computer and use it in GitHub Desktop.

Select an option

Save jpawlyn/21add7c5cad7a8edfa911457b2f63830 to your computer and use it in GitHub Desktop.
/* global self, clients, importScripts, workbox */
importScripts(
"https://storage.googleapis.com/workbox-cdn/releases/7.3.0/workbox-sw.js"
);
// workbox sw chrome console logging is on by default for localhost
// but let's turn it on for production too
// see https://developer.chrome.com/docs/workbox/troubleshooting-and-logging#without_a_bundler
workbox.setConfig({
debug: true
});
const updateServiceWorker = '2' // Increment this value if offline fallback page changes so it gets re-cached
const CACHE_VERSION = 'v1';
const { CacheFirst, NetworkFirst, NetworkOnly } = workbox.strategies;
const { registerRoute } = workbox.routing;
const { ExpirationPlugin } = workbox.expiration;
self.skipWaiting();
// ensure that the service worker takes control immediately without requiring a reload
// see https://frontendian.co/service-workers
workbox.core.clientsClaim();
// For assets (scripts, styles and images), we use cache first
registerRoute(
({ request }) => request.destination === "script" ||
request.destination === "style",
new CacheFirst({
cacheName: `assets-styles-and-scripts-${CACHE_VERSION}`,
plugins: [
new ExpirationPlugin({
maxEntries: 100
})
]
})
)
registerRoute(
({ request }) => request.destination === "image",
new CacheFirst({
cacheName: `assets-images-${CACHE_VERSION}`,
plugins: [
new ExpirationPlugin({
maxEntries: 100
})
]
})
)
const offline_cached_paths = <%= raw @offline_cached_paths.to_s %>;
const warm_cached_paths = <%= raw @warm_cached_paths.to_s %>;
const cached_paths = offline_cached_paths.concat(warm_cached_paths);
const no_fallback_paths = <%= raw @no_fallback_paths.to_s %>;
registerRoute(
({ request, url }) => !cached_paths.includes(url.pathname) && !no_fallback_paths.includes(url.pathname) &&
(request.destination === 'document' || request.destination === ''),
new NetworkOnly()
)
// For pages, network first
const documentsStrategyOptions = {
cacheName: `documents-${CACHE_VERSION}`,
matchOptions: { ignoreVary: true },
plugins: [
new ExpirationPlugin({
maxEntries: 100
})
]
}
// see https://developer.chrome.com/docs/workbox/modules/workbox-routing
registerRoute(
({ request, url }) => !no_fallback_paths.includes(url.pathname) && (request.destination === 'document' ||
request.destination === ''),
new NetworkFirst(documentsStrategyOptions)
)
// Warm runtime cache so urls are cached before they are visited
const { warmStrategyCache } = workbox.recipes;
const strategy = new NetworkFirst(documentsStrategyOptions);
warmStrategyCache({ urls: warm_cached_paths, strategy });
// Warm runtime cache with an offline URL
const offlineUrls = ['/offline.html'];
const offlineStrategy = new NetworkFirst();
warmStrategyCache({ urls: offlineUrls, strategy: offlineStrategy });
// Trigger a 'catch' handler when any of the other routes fail to generate a response
const { setCatchHandler } = workbox.routing;
setCatchHandler(async ({ event }) => {
switch (event.request.destination) {
case '':
case 'document':
return offlineStrategy.handle({ event, request: offlineUrls[0] })
default:
return Response.error()
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment