angulargithub-pagesangular-service-workerangular-cli-v9

Angular service worker doesn't cache assets once deployed on Github pages (sub-directory)


I developed an Angular PWA demo application (Angular v9.1.3), implementing performance and freshness strategies.

Locally it works perfectly, even offline. But once deployed on Github pages, it is not working anymore as expected:

  1. performance strategy keeps fetching all Requests from the network, not from the cache
  2. Once offline, the app doesn't work, as nothing seems to be cached


I use angular-cli-ghpages to deploy to gh-pages with the following command (angular-pwa-boilerplate is the Repo name):

    ng deploy --base-href=/angular-pwa-boilerplate/


Once deployed, I adjust the start_url property of the web-manifest file to "/angular-pwa-boilerplate/" to reflect the subdirectory structure.

Even though the scope path seems being correct and the app is installable, the service worker does not caches the assets nor the Http Responses (while locally all is fine).

I read many articles about it, but all the fixes did not work:

  1. Use a relative path ./ for the service worker file:
    ServiceWorkerModule.register('./ngsw-worker.js', ...)
  2. Set relative values for scope and start_url in manifest file:
    "scope": ".",
    "start_url":" "./"


Here the DEMO and Github Repo

It seems also that there is still some ongoing work on this topic.


UPDATE

I noticed that if I leave start_url: "/" (hence without adjusting it to the base-href), Angular Service Worker and its caching strategies work like a charm also on gh-pages.


However the app is no more installable:

enter image description here


Solution

  • This is what you see if you access the debug info:

    NGSW Debug Info:
    
    Driver state: EXISTING_CLIENTS_ONLY (Degraded due to: Hash mismatch (cacheBustedFetchFromNetwork): https://pacoita.github.io/angular-pwa-boilerplate/manifest.webmanifest: expected cbcd3fc3623610507d05fab49a40b0fcb22f47bb, got 69c8bc4c8eb903528013fe49ac2c8a521b120901 (after cache busting)
    Error: Hash mismatch (cacheBustedFetchFromNetwork): https://pacoita.github.io/angular-pwa-boilerplate/manifest.webmanifest: expected cbcd3fc3623610507d05fab49a40b0fcb22f47bb, got 69c8bc4c8eb903528013fe49ac2c8a521b120901 (after cache busting)
        at PrefetchAssetGroup.<anonymous> (https://pacoita.github.io/angular-pwa-boilerplate/ngsw-worker.js:734:35)
        at Generator.next (<anonymous>)
        at fulfilled (https://pacoita.github.io/angular-pwa-boilerplate/ngsw-worker.js:174:62))
    Latest manifest hash: 4f36c4b0eb2e39ccabb57986bc3191e39cabad0c
    Last update check: 1m45s215u
    
    === Version 4f36c4b0eb2e39ccabb57986bc3191e39cabad0c ===
    
    Clients: 
    
    === Idle Task Queue ===
    Last update tick: 1m50s390u
    Last update run: 1m45s381u
    Task queue:
    
    
    Debug log:
    
    [2m40s282u] Ignoring invalid request: 'only-if-cached' can be set only with 'same-origin' mode Driver.fetch(https://pacoita.github.io/angular-pwa-boilerplate/, cache: only-if-cached, mode: no-cors)
    [2m34s503u] Error(Hash mismatch (cacheBustedFetchFromNetwork): https://pacoita.github.io/angular-pwa-boilerplate/manifest.webmanifest: expected cbcd3fc3623610507d05fab49a40b0fcb22f47bb, got 69c8bc4c8eb903528013fe49ac2c8a521b120901 (after cache busting), Error: Hash mismatch (cacheBustedFetchFromNetwork): https://pacoita.github.io/angular-pwa-boilerplate/manifest.webmanifest: expected cbcd3fc3623610507d05fab49a40b0fcb22f47bb, got 69c8bc4c8eb903528013fe49ac2c8a521b120901 (after cache busting)
        at PrefetchAssetGroup.<anonymous> (https://pacoita.github.io/angular-pwa-boilerplate/ngsw-worker.js:734:35)
        at Generator.next (<anonymous>)
        at fulfilled (https://pacoita.github.io/angular-pwa-boilerplate/ngsw-worker.js:174:62)) initializeFully for 4f36c4b0eb2e39ccabb57986bc3191e39cabad0c
    [2m6s104u] TypeError(Failed to fetch, TypeError: Failed to fetch) Driver.fetch(https://pacoita.github.io/angular-pwa-boilerplate/)
    

    NOTE: The debug info is normally available as /ngsw/state, but this does not work when serving from a sub-path. This will be fixed with angular/angular#31082. I just hacked my way to the debug info.

    Based on the debug info, it seems that there is a hash mismatch for the manifest.webmanifest, which causes the ServiceWorker to not work properly. This means that the contents of the file that is served to the browser is different than the content of the file when the ngsw.json file was generated (during ng build). This is because you are modifying the file after being built.

    In order to avoid this you should modify the source file before building (and let the changes propagate to the built artifacts.

    Have you also tried using --baseHref option of ng build (i.e. ng build --prod --baseHref=/angular-pwa-boilerplate/ ...)? This should take care of updating any URLs (including manigest.webmanifest) automatically.