I am implementing a Service Worker with a React app. I am using the Service Worker to add an Authorization header to every fetch request coming from the controlled window (API calls as well as images and other assets). The React app gets a token from an identity provider (Keycloak), and then sends this to the Service Provider. Here is a simplified flow:
navigator?.serviceWorker?.register('/myServiceWorker.js', { scope: '/' }).then(() => {
navigator.serviceWorker.controller?.postMessage({
type: 'MY_TOKEN'
});
}
The interesting thing is that this works fine on first load, but when I open another tab and run the same app, it doesn't work - I can't access the navigator.serviceWorker.controller and use the postMessage method - because navigator.serviceWorker.controller is undefined.
I think this is because there is only one copy of the Service Worker, but 2 copies of the React app running. When the second tab opens, the React script runs, loads the Service Worker, but the browser sees that the new tab is within the scope of the Service Worker, so it does not run the initialization of the Service Worker again. However, this seems to avoid having the Service Worker claim the new window or something which prevents the Service Worker from registering the new window with a controller? Or is it just a race condition of some kind?
EDIT: Additionally, and somewhat strangely, if I refresh the 2nd tab, it will work every other time. This seems to be reliable.
Hello! I'm having the same problem loading my service workers in a new tab. Have you found any solution to this problem?