Hello,
Before I write my question, I am sure there are a couple of coding errors of this page: https://workboxjs.org/examples/workbox-sw/
workboxSW.precache([{
url: 'precached.txt',
revision: '43011922c2aef5ed5ee3731b11d3c2cb', <- Why is there a comma here?
}]);
Corrected Version:
workboxSW.precache([{
url: 'precached.txt',
revision: '43011922c2aef5ed5ee3731b11d3c2cb'
}]);
Also this bit of code:
workboxSW.router.registerRoute(
'https://httpbin.org/image/(.*)',
workboxSW.strategies.cacheFirst({
cacheName: 'images',
cacheExpiration: {
maxEntries: 2,
maxAgeSeconds: 7 * 24 * 60 * 60, <- Why is there a comma here?
},
cacheableResponse: {statuses: [0, 200]}, <- Why is there a comma here?
})
);
Corrected Version:
workboxSW.router.registerRoute(
'https://httpbin.org/image/(.*)',
workboxSW.strategies.cacheFirst({
cacheName: 'images',
cacheExpiration: {
maxEntries: 2,
maxAgeSeconds: 7 * 24 * 60 * 60
},
cacheableResponse: {statuses: [0, 200]}
})
);
Ok on to my question, I am trying to convert my service worker from sw-toolbox to workbox, my code I am stuck on converting is here:
global.toolbox.router.get('/(.*)', function(request, values, options) {
return global.toolbox.fastest(request, values, options).catch(function(error) {
if (request.method === 'GET' && request.headers.get('accept').includes('text/html')) {
return toolbox.cacheOnly(new Request('offline'), values, options);
}
throw error;
});
}, {networkTimeoutSeconds: 4});
Looking at Workbox Caching list found here: https://workboxjs.org/reference-docs/latest/module-workbox-runtime-caching.html
You don't seem to have a toolbox.fastest is there one in toolbox that does the same thing?
toolbox.fastest = Request the resource from both the cache and the network in parallel.
I'm guessing toolbox.fastest has been replaced with workboxSW.strategies.staleWhileRevalidate.
I think my biggest problem is the method GET, been reading other issues and seems not straight forward with workbox.
Anyway, I am really stuck in the correct way to convert this piece of code? So I thought I ask the experts here.
This is my failed attempt:
workboxSW.router.registerRoute('/(.*)', function(request, values, options) {
return workboxSW.strategies.staleWhileRevalidate(request, values, options).catch(function(error) {
if (request.method === 'GET' && request.headers.get('accept').includes('text/html')) {
return workboxSW.strategies.cacheOnly(new Request('offline'), values, options);
}
throw error;
});
}, {networkTimeoutSeconds: 4});
Hello @ayumihamsaki! Thanks for using Workbox, and for your feedback.
Regarding the dangling commas, the general idea is explained here, and it's something required by the Google JavaScript style guide.
Regarding toolbox.fastest, yes, workboxSW.strategies.staleWhileRevalidate is the closest equivalent. (It's slightly different, in that the cached response is always used first with staleWhileRevalidate, instead of "racing" with the network.)
Regarding your migration question, the equivalent code would be:
workboxSW.router.registerRoute(
'/(.*)',
({event}) => {
return workboxSW.strategies.staleWhileRevalidate({event}).catch((error) => {
// Checking for a navigation request is a better idea than checking for
// Accept: text/html
if (event.request.mode === 'navigate') {
// This assumes that you have /offline.html cached already, perhaps
// via your precache() call.
return caches.match('/offline.html');
}
return error;
});
}
);
Thank you Jeff for your reply and all the extra information including dangling commas (I'm learning new things). Good luck with launching workbox V2.0.0
@jeffposnick Sorry to bother you as I know you must be a busy person. Your code looks flawless to me, but I am getting this error:
Uncaught TypeError: workboxSW.strategies.staleWhileRevalidate(...).catch is not a function
at Object.workboxSW.router.registerRoute [as handle] (sw.js:1)
at Router$$1.handleRequest (workbox-sw.prod.v2.0.0.js:16)
at _isListenerRegistered.self.addEventListener (workbox-sw.prod.v2.0.0.js:16)
To me the catch looks ok, so I thought I'd ask your advice.
@ayumihamsaki @jeffposnick
The staleWhileRevalidate has a function that returns a promise handle() which I think was left out in Jeff's original code sample.
workboxSW.router.registerRoute(
'/(.*)',
({event}) => {
return workboxSW.strategies.staleWhileRevalidate().handle({event}).catch((error) => {
// Checking for a navigation request is a better idea than checking for
// Accept: text/html
if (event.request.mode === 'navigate') {
// This assumes that you have /offline.html cached already, perhaps
// via your precache() call.
return caches.match('/offline.html');
}
return error;
});
}
);
Hi I have tested this code on a production pwa and it is working fine, online and offline.
Thank you both for your help. I will close this issue.
@gauntface I think the .catch() in that code doesn't ever seem to be called. So even though my offline page is pre cached, when I navigate to a URL that isn't cached yet, I just get the generic This site can't be reached Chrome error page, and this warning in the console:
The FetchEvent for <url> resulted in a network error response: the promise was resolved with an error response object.
Promise resolved (async)
_isListenerRegistered.self.addEventListener @ router.js:101
instead of the fallback to my pre cached offline page. Any ideas?
@andrewcoelho could you open a seperate bug with info, example code and if possible an example repo / site we can look at.
Most helpful comment
@ayumihamsaki @jeffposnick
The staleWhileRevalidate has a function that returns a promise
handle()which I think was left out in Jeff's original code sample.