React PWA Workbox InvalidStateError

175 views Asked by At

Few users on IOS devices get error InvalidStateError newestWorker is null.

This is my register function using workbox-window just like the documentation mentioned

 if ('serviceWorker' in navigator) {
    const wb = new Workbox(`${process.env.PUBLIC_URL}/service-worker.js`)
    const showSkipWaitingPrompt = async (event) => {
        wb.addEventListener('controlling', () => {
            window.location.reload()
        })
        wb.messageSkipWaiting()
    }
    wb.addEventListener('waiting', (event) => {
        showSkipWaitingPrompt(event)
    })
    wb.register()
}

I call it on top level in index.js (main file)

And this is how I call the update:

const updateVersion = () => {
    navigator.serviceWorker?.getRegistrations().then((registrations) => {
        try {
            for (const reg of registrations) {
                reg.update()
            }
        } catch (error) {
            if (error.name !== 'InvalidStateError') {
                throw error   // here should be better error handling
            }
        }
    })
}

 const { pathname } = useLocation()   // from react-router-dom
 useEffect(() => {
     updateVersion()
 }, [pathname])

This is what I have in my service worker

import { clientsClaim } from 'workbox-core'
import { ExpirationPlugin } from 'workbox-expiration'
import { precacheAndRoute, createHandlerBoundToURL, cleanupOutdatedCaches } from 'workbox-precaching'
import { registerRoute } from 'workbox-routing'
import { StaleWhileRevalidate } from 'workbox-strategies'

clientsClaim();
cleanupOutdatedCaches();
precacheAndRoute((self as any).__WB_MANIFEST);
const fileExtensionRegexp = new RegExp('/[^/?]+\\.[^/]+$');
registerRoute(
    ({ request, url }) => {
        if (request.mode !== 'navigate') {
            return false;
        }

        if (url.pathname.startsWith('/_')) {
            return false;
        }

        if (url.pathname.match(fileExtensionRegexp)) {
            return false;
        } 

        return true;
    },
    createHandlerBoundToURL(process.env.PUBLIC_URL + '/index.html')
);

self.addEventListener('message', (event) => {
    if (event.data && event.data.type === 'SKIP_WAITING') {
        (self as any).skipWaiting();
    }
});

Why that error happens and how I can prevent / handle it? Should I somehow unregister and register the SW again?

  • Workbox version 6.5.3
  • React version: 18.2.0

No more information about the error exist.

0

There are 0 answers