Routing
Original source (Apache 2.0 License). Adapted for Serwist’s usage.
Introduction
A service worker can intercept network requests for a page. It may respond to the browser with cached content, content from the network or content generated in the service worker.
Routing is how Serwist allows different functions to handle different requests.
When a network request is intercepted, Serwist attempts to respond to the request using the supplied routes and handlers.
The main things to note from the above are:
- The method of a request is important. By default, routes are registered for
GET
requests. If you wish to intercept other types of requests, you’ll need to specify the method. - The register order is important. If multiple registered routes can handle a request, the route that is registered first will be used to respond to the request.
Applying caching strategies with route matching
The Serwist class exposes the registerCapture
method to allow you to match a pattern of routes to a caching strategy. registerCapture
accepts two arguments:
- A string, regular expression, or a match callback to specify route matching criteria.
- A handler for the route — typically a built-in
Strategy
.
You may also use the runtimeCaching option of Serwist’s constructor. It is essentially a syntactic sugar for registerCapture.
When the service worker intercepts a network request, Serwist tries to match the URL of the request to one of the registered handlers, which will then be used to generate a response. In the following example, we register a route that matches incoming same-origin image requests, applying the CacheFirst
strategy.
import { CacheFirst, Serwist } from "serwist";
const serwist = new Serwist();
serwist.registerCapture(({ request, sameOrigin }) => {
return sameOrigin && request.destination === "image";
}, new CacheFirst());
serwist.addEventListeners();
Matching all navigation requests
NavigationRoute
allows you to match all navigation requests. If your site is a single page application, you can use NavigationRoute
to return a specific response for all navigation requests:
Alternatively, you can use precacheOptions.navigateFallback
:
Setting a default handler
If you want to supply a handler for requests that don’t match any route at all, you can set a default handler.
import { CacheFirst } from "serwist";
const cacheFirst = new CacheFirst();
// Example: If HTTP method is `GET`, use the `CacheFirst` strategy,
// go to the network otherwise.
serwist.setDefaultHandler(({ event, request, url, params }) => {
if (request.method === "GET") {
return cacheFirst.handle({ event, request, url, params });
}
return fetch(request);
});
serwist.addEventListeners();
Setting a catch handler
In the case of any of your routes throwing an error, you can capture and degrade gracefully by setting a catch handler.
// Example: Setting up offline fallbacks.
serwist.setCatchHandler(async ({ request }) => {
const dest = request.destination;
if (dest === "document") {
const match = await serwist.matchPrecache("/offline.html");
return match || Response.error();
}
if (dest === "image") {
const match = await serwist.matchPrecache("/fallback.png");
return match || Response.error();
}
if (dest === "font") {
const match = await serwist.matchPrecache("/fonts/fallback.woff2");
return match || Response.error();
}
return Response.error();
});
Defining a route for non-GET requests
All routes by default are assumed to be for GET
requests.
If you would like to route requests of other HTTP methods, you need to specify the method when registering the route like so:
import { NetworkFirst } from "serwist";
serwist.registerCapture(/^\/api\/.*/, new NetworkFirst(), "POST");
serwist.addEventListeners();