DEV Community

negue
negue

Posted on • Edited on

Service worker registered yet?

TL;DR

Having a little app, trying to get angular's service worker registered, took longer than expected.

Using the normal ng add @angular/pwa --project *project-name* added all needed files. Yet, building / serving with --prod it doesn't register anything.

Good. Lets google.

Many sites/pages/hours later, nothing really answered the issue, all there was is "use a custom register code" like

if ('serviceWorker' in navigator && environment.production) {
  navigator.serviceWorker.register('./ngsw-worker.js');
}

Well that worked, but still if this was the only way to add the worker, why did Angular's ServiceWorkerModule.register('./ngsw-worker.js') not work then?

Lets debug.

At first I thought it was because of using nrwl and something messed up with the angular.json.

Created a second app in my workspace, added the pwa and well there it works.

Now figuring out why my app just doesn't want to register it there ...

Added part by part to the newly app, everything worked until I added NgRx EffectModule. Odd. The Effects-Class was empty, just had some services injected.

Some more hours of searching later, why this could be a reason that it registers the normal way...

  • Wrong Base Href? - Checked, No changes
  • default router redirect '' -> 'page' - Removed, still not working
  • Updated to 8.0-rc3 - Still not working

Looking at the source-code of ServiceWorkerModule I saw that it uses ApplicationRef.isStable()-Observable to wait to register. But isStable() just stays false.

Luckily I also saw that the .register-Method also has an options argument. And inside that, you can set registrationStrategy. (Which isn't wasn't listed in the docs, by the time I wrote this article.)

Possible Strategy's:

  • registerWhenStable (default)
  • registerWithDelay:*delay*
  • registerImmediately

Solution.

  ServiceWorkerModule.register('./ngsw-worker.js', {
    enabled: environment.production,
    registrationStrategy: 'registerImmediately'
  }),

Using either registerWithDelay or registerImmediately at least registers it without having a custom register-code. (So it should be future proof, using only the ServiceWorkerModule.register-call)

Top comments (0)