🐛(service-worker) force reload new service worker
When multiple tabs are open, the new service worker can stay in the "waiting" state and not be activated until the other tabs with the old service worker are closed. We fix this by forcing the other tabs to reload the page when a new service worker is detected. All tabs will then be reloaded and the new service worker will be activated.
This commit is contained in:
@@ -21,9 +21,11 @@ describe('useSWRegister', () => {
|
||||
reject('error');
|
||||
}),
|
||||
);
|
||||
|
||||
Object.defineProperty(navigator, 'serviceWorker', {
|
||||
value: {
|
||||
register: registerSpy,
|
||||
addEventListener: jest.fn(),
|
||||
},
|
||||
writable: true,
|
||||
});
|
||||
@@ -31,6 +33,10 @@ describe('useSWRegister', () => {
|
||||
render(<TestComponent />);
|
||||
|
||||
expect(registerSpy).toHaveBeenCalledWith('/service-worker.js?v=123456');
|
||||
expect(navigator.serviceWorker.addEventListener).toHaveBeenCalledWith(
|
||||
'controllerchange',
|
||||
expect.any(Function),
|
||||
);
|
||||
});
|
||||
|
||||
it('checks service-worker is not register', () => {
|
||||
|
||||
@@ -8,9 +8,33 @@ export const useSWRegister = () => {
|
||||
) {
|
||||
navigator.serviceWorker
|
||||
.register(`/service-worker.js?v=${process.env.NEXT_PUBLIC_BUILD_ID}`)
|
||||
.then((registration) => {
|
||||
registration.onupdatefound = () => {
|
||||
const newWorker = registration.installing;
|
||||
if (!newWorker) {
|
||||
return;
|
||||
}
|
||||
|
||||
newWorker.onstatechange = () => {
|
||||
if (
|
||||
newWorker.state === 'installed' &&
|
||||
navigator.serviceWorker.controller
|
||||
) {
|
||||
newWorker.postMessage({ type: 'SKIP_WAITING' });
|
||||
}
|
||||
};
|
||||
};
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('Service worker registration failed:', err);
|
||||
});
|
||||
|
||||
const currentController = navigator.serviceWorker.controller;
|
||||
navigator.serviceWorker.addEventListener('controllerchange', () => {
|
||||
if (currentController) {
|
||||
window.location.reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
}, []);
|
||||
};
|
||||
|
||||
@@ -65,6 +65,13 @@ self.addEventListener('install', function (event) {
|
||||
event.waitUntil(self.skipWaiting());
|
||||
});
|
||||
|
||||
self.addEventListener('message', (event) => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
||||
if (event.data?.type === 'SKIP_WAITING') {
|
||||
void self.skipWaiting();
|
||||
}
|
||||
});
|
||||
|
||||
self.addEventListener('activate', function (event) {
|
||||
const cacheAllow = SW_VERSION;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user