Serwist.
A Swiss Army knife for service workers.
npm install -D serwist @serwist/build
Dead simple. You need as much as ten lines of code to get started.
import { Serwist } from "serwist";
const serwist = new Serwist({
precacheEntries: self.__SW_MANIFEST,
skipWaiting: true,
clientsClaim: true,
});
serwist.addEventListeners();
Customizable. Just do it your way.
import type { PrecacheEntry, SerwistGlobalConfig } from "serwist";
import { Serwist } from "serwist";
import { defaultCache } from "@serwist/vite/worker";
declare global {
interface WorkerGlobalScope extends SerwistGlobalConfig {
// Change this attribute's name to your \`injectionPoint\`.
// \`injectionPoint\` is an InjectManifest option.
// See https://serwist.pages.dev/docs/build/configuring
__SW_MANIFEST: (PrecacheEntry | string)[] | undefined;
}
}
declare const self: ServiceWorkerGlobalScope;
const serwist = new Serwist({
// A list of URLs that should be cached. Usually, you don't generate
// this list yourself; rather, you'd rely on a Serwist build tool/your framework
// to do it for you. In this example, it is generated by \`@serwist/vite\`.
precacheEntries: self.__SW_MANIFEST,
// Options to customize how Serwist precaches the URLs.
precacheOptions: {
// Whether outdated caches should be removed.
cleanupOutdatedCaches: true,
concurrency: 10,
ignoreURLParametersMatching: [],
},
// Whether the service worker should skip waiting and become the active one.
skipWaiting: true,
// Whether the service worker should claim any currently available clients.
clientsClaim: true,
// Whether navigation preloading should be used.
navigationPreload: false,
// Whether Serwist should log in development mode.
disableDevLogs: true,
// A list of runtime caching entries. When a request is made and its URL match
// any of the entries, the response to it will be cached according to the matching
// entry's \`handler\`. This does not apply to precached URLs.
runtimeCaching: defaultCache,
// Other options...
// See https://serwist.pages.dev/docs/serwist/core/serwist
});
serwist.addEventListeners();
Interoperable. The Serwist API. The Service Worker API. It doesn't matter.
import type { PrecacheEntry, SerwistGlobalConfig } from "serwist";
import { BackgroundSyncQueue, Serwist } from "serwist";
import { defaultCache } from "@serwist/vite/worker";
declare global {
interface WorkerGlobalScope extends SerwistGlobalConfig {
__SW_MANIFEST: (PrecacheEntry | string)[] | undefined;
}
}
declare const self: ServiceWorkerGlobalScope;
self.skipWaiting();
self.addEventListener("activate", () => self.clients.claim());
const queue = new BackgroundSyncQueue("myQueueName");
const serwist = new Serwist({
precacheEntries: self.__SW_MANIFEST,
precacheOptions: {
cleanupOutdatedCaches: true,
concurrency: 10,
ignoreURLParametersMatching: [],
},
skipWaiting: false,
clientsClaim: false,
navigationPreload: false,
disableDevLogs: true,
runtimeCaching: defaultCache,
});
self.addEventListener("fetch", (event) => {
const url = new URL(event.request.url);
// For "/legacy-post" with the method "POST", this simply makes a network request,
// but if that fails due to a network problem, the request is added to the background
// synchronization queue and will be retried later.
if (event.request.method === "POST" && url.origin === location.origin && url.pathname === "/legacy-post") {
const backgroundSync = async () => {
try {
const response = await fetch(event.request.clone());
return response;
} catch (error) {
await queue.pushRequest({ request: event.request });
return Response.error();
}
};
event.respondWith(backgroundSync());
}
});
serwist.addEventListeners();