I'm switching from sw-toolbox to Workbox and I can't figure out how to use setDefaultHandler().
If I try (as stated in the documentation linked above):
workboxSW.router.setDefaultHandler({
handler: new workbox.runtimeCaching.CacheFirst()
});
I get an error that runtimeCaching is undefined:
Uncaught ReferenceError: router is not defined
So.. how do I use it and configure it in a way similar to how I could configure sw-toolbox:
toolbox.options.cache = {
name: "default",
maxEntries: 128,
maxAgeSeconds: (60*60*24), // 24hrs
};
toolbox.router.default = toolbox.cacheFirst;
I would like to be able to do something like this:
workboxSW.router.setDefaultHandler({
handler: workboxSW.strategies.cacheFirst({
cacheName: 'default',
cacheExpiration: {
maxEntries: 128,
},
cacheableResponse: {statuses: [0, 200]},
})
});
..which doesn't throw compile errors but when I use it I get this:
Uncaught (in promise) TypeError: Request method 'POST' is unsupported
..and my Cache Storage for 'default' remains empty..?
Since my edits for Jeff's first solution were rejected I'll just go ahead and submit an answer myself.
Jeff's sample came close. He suggested:
You could check for the request type in the default handler, and only apply the cache-first strategy to GET requests:
workboxSW.router.setDefaultHandler({
handler: (args) => {
if (args.event.request.method === 'GET') {
return workboxSW.strategies.cacheFirst(args);
}
return fetch(args.event.request);
},
});
It's the right approach but the example code he provided didn't work. The handler argument needs a handler, not a strategy. Luckily, strategies have exactly one (public) method, called "handle".
So I modified his code a little; First, I create a strategy called defaultStrategy
with all the options I need. Then, in the setDefaultHandler call, I return defaultStrategy.handle(args)
instead of the CacheFirst constructor. That's it!
// Register 'default'
var defaultStrategy = workboxSW.strategies.cacheFirst({
cacheName: "default",
cacheExpiration: {
maxEntries: 128,
// more options..
},
cacheableResponse: {statuses: [0, 200]},
});
workboxSW.router.setDefaultHandler({
handler: (args) => {
if (args.event.request.method === 'GET') {
return defaultStrategy.handle(args);
}
return fetch(args.event.request);
},
});
UPDATE: Workbox v3
As I pointed out in the comments below, the above code doesn't work with Workbox v3. Use this instead:
// Register 'default'
var defaultStrategy = workbox.strategies.cacheFirst ({
cacheName: "your.cache.name",
plugins: [
new workbox.expiration.Plugin({
maxEntries: 128,
maxAgeSeconds: 7 * 24 * 60 * 60, // 1 week
purgeOnQuotaError: true, // Opt-in to automatic cleanup
}),
new workbox.cacheableResponse.Plugin({
statuses: [0, 200] // for opague requests
}),
],
});
workbox.routing.setDefaultHandler(
(args) => {
if (args.event.request.method === 'GET') {
return defaultStrategy.handle(args); // use default strategy
}
return fetch(args.event.request);
}
);
workboxSW.router.setDefaultHandler({
handler: workboxSW.strategies.cacheFirst({...})
});
is the right syntax in general.
I believe that you're seeing
Uncaught (in promise) TypeError: Request method 'POST' is unsupported
because the default handler is triggered for all HTTP requests that don't match any explicit route, including HTTP POST
requests. But a HTTP POST
request can't be used with the Cache Storage API, and an exception similar to what you're seeing will be thrown when the cache-first strategy attempts to store the request/response pair in the cache.
In this particular case, when you know that your web app is going to make HTTP POST requests, you could take one of two approaches.
You could check for the request type in the default handler, and only apply the cache-first strategy to GET
requests:
workboxSW.router.setDefaultHandler({
handler: (args) => {
if (args.event.request.method === 'GET') {
return workboxSW.strategies.cacheFirst(args);
}
return fetch(args.event.request);
},
});
Alternatively, you could create a wildcard route that matches all requests, and take advantage of the fact that by default, routes will only match HTTP GET
:
workboxSW.router.registerRoute(
/./, // This should match all requests.
workboxSW.strategies.cacheFirst({...}),
'GET' // This is the default, and can be left out.
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With