I am trying to understand the Service Worker API, and I know the bits and parts about registering a Service Worker.
As stated in the API doc, if a service worker update is found, the service worker is registered and added to the queue. This SW takes over a page if and only if, the page is closed and opened again.That is, A window is closed and reopened again.
Now, this has a few downfalls:
The user might be seeing a previous version that might have a very serious grammatical mistake, or whatever.
The user needs to be somehow notified that the content has changed and that a referesh would do it.
I know how to tell the SW.js
to skipWaiting()
and take over. I also know how to send a message to the SW.js
telling it that the user wants a automatic refresh.
However, what I do not know is how to know whether a new SW is actually in a waiting state.
I have used this:
navigator.serviceWorker.ready.then((a) => {
console.log("Response, ", a);
if (a.waiting !== null && a.waiting.state === "installed") {
console.log("okay");
}
});
However, it usually returns the waiting state as null
.(Possibly because the SW is still installing when the request is fired.)
How can I know on the client page that a waiting service worker is available?
I am trying to understand the Service Worker API, and I know the bits and parts about registering a Service Worker.
As stated in the API doc, if a service worker update is found, the service worker is registered and added to the queue. This SW takes over a page if and only if, the page is closed and opened again.That is, A window is closed and reopened again.
Now, this has a few downfalls:
The user might be seeing a previous version that might have a very serious grammatical mistake, or whatever.
The user needs to be somehow notified that the content has changed and that a referesh would do it.
I know how to tell the SW.js
to skipWaiting()
and take over. I also know how to send a message to the SW.js
telling it that the user wants a automatic refresh.
However, what I do not know is how to know whether a new SW is actually in a waiting state.
I have used this:
navigator.serviceWorker.ready.then((a) => {
console.log("Response, ", a);
if (a.waiting !== null && a.waiting.state === "installed") {
console.log("okay");
}
});
However, it usually returns the waiting state as null
.(Possibly because the SW is still installing when the request is fired.)
How can I know on the client page that a waiting service worker is available?
Share Improve this question edited Apr 2, 2021 at 9:02 Serge Stroobandt 31.5k9 gold badges120 silver badges109 bronze badges asked Jun 1, 2016 at 15:53 codecode 2,1631 gold badge25 silver badges50 bronze badges1 Answer
Reset to default 22Here's some code that will detect and allow you to handle various states whenever there's a new or updated service worker registration.
Please note that the log message assumes that skipWaiting()
is not being called during the service worker's installation; if it is being called, then instead of having to close all tabs to get the new service worker to activate, it will just activate automatically.
if ('serviceWorker' in navigator) {
window.addEventListener('load', async function() {
const registration = await navigator.serviceWorker.register('/service-worker.js');
if (registration.waiting && registration.active) {
// The page has been loaded when there's already a waiting and active SW.
// This would happen if skipWaiting() isn't being called, and there are
// still old tabs open.
console.log('Please close all tabs to get updates.');
} else {
// updatefound is also fired for the very first install. ¯\_(ツ)_/¯
registration.addEventListener('updatefound', () => {
registration.installing.addEventListener('statechange', () => {
if (event.target.state === 'installed') {
if (registration.active) {
// If there's already an active SW, and skipWaiting() is not
// called in the SW, then the user needs to close all their
// tabs before they'll get updates.
console.log('Please close all tabs to get updates.');
} else {
// Otherwise, this newly installed SW will soon become the
// active SW. Rather than explicitly wait for that to happen,
// just show the initial "content is cached" message.
console.log('Content is cached for the first time!');
}
}
});
});
}
});
}