Sitelet https://web.archive.org/web/20210326154901/https://github.com/angular/angular/issues/41085
Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default @angular/pwa install doesn't pass Chrome 89 offline support detection #41085

Open
clementcontet opened this issue Mar 5, 2021 · 24 comments
Open

Comments

@clementcontet
Copy link

@clementcontet clementcontet commented Mar 5, 2021

🐞 bug report

Affected Package

@angular/pwa

Is this a regression?

No, I think it's because of Chrome's update: https://developer.chrome.com/blog/improved-pwa-offline-detection/

Description

When creating an Angular app with PWA support, the default template doesn't pass Chrome's "offline support" detection anymore.
So that apps created this way won't be installable in a near future (starting with Chrome 93)

🔬 Minimal Reproduction

Just create the default template app:


$ ng new template-angular
$ cd template-angular
$ ng add @angular/pwa --project template-angular
$ ng build --prod

Code: https://github.com/clementcontet/template-angular

Hosted result: https://template-angular-f3cdb.web.app/

🔥 Exception or Error

Chrome 89 says:
image

🌍 Your Environment

Angular Version:


Angular CLI: 11.2.3
Node: 12.18.0
OS: win32 x64

Angular: 11.2.4
... animations, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router
... service-worker
Ivy Workspace: Yes

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1102.3
@angular-devkit/build-angular   0.1102.3
@angular-devkit/core            11.2.3
@angular-devkit/schematics      11.2.3
@angular/cli                    11.2.3
@schematics/angular             11.2.3
@schematics/update              0.1102.3
rxjs                            6.6.6
typescript                      4.1.5
@josemalm32
Copy link

@josemalm32 josemalm32 commented Mar 5, 2021

Same problem here...

@ngbot ngbot bot added this to the needsTriage milestone Mar 5, 2021
@gkalpak gkalpak self-assigned this Mar 5, 2021
@gkalpak
Copy link
Member

@gkalpak gkalpak commented Mar 5, 2021

Thx for reporting this.

I looked into it and the problem is that the Angular ServiceWorker will only return the index URL (i.e. a successful response while offline for a URL that is not in the cache) only for navigation requests. And the request made by Chrome to determine installability is not a navigation request.

For reference, the request for determining installability has a mode of cors and uses web manifest's start_url.

More investigation is needed to determine the best way to approach this for the Angular ServiceWorker.
In the meantime, one workaround is to set your web manifest's start_url to something that will be in the cache (for example, index.html, which is by default part of an eagerly installed asset cache).

@jelbourn jelbourn added the P3 label Mar 5, 2021
@ngbot ngbot bot modified the milestones: needsTriage, Backlog Mar 5, 2021
@zedL

This comment was marked as off-topic.

@gkalpak

This comment was marked as off-topic.

@zedL
Copy link

@zedL zedL commented Mar 14, 2021

@gkalpak I tried to implement the workaround without success.
I modified my webmanifest.json "start_url": "./index.html" and ngsw-config.json.
"assetGroups": [ { "name": "app", "installMode": "prefetch", "resources": { "files": [ "/favicon.ico", "/index.html", "/webmanifest.json", "/*.css", "/*.js" ], "urls": [ ...] } },

The index.html file get not prefetched and the call from chrome to check installable pwa still fail.
Any idea why?
PWA is here https://traact.app

@pette9
Copy link

@pette9 pette9 commented Mar 14, 2021 •

@gkalpak I tried to implement the workaround without success.
I modified my webmanifest.json "start_url": "./index.html" and ngsw-config.json.
"assetGroups": [ { "name": "app", "installMode": "prefetch", "resources": { "files": [ "/favicon.ico", "/index.html", "/webmanifest.json", "/*.css", "/*.js" ], "urls": [ ...] } },

The index.html file get not prefetched and the call from chrome to check installable pwa still fail.
Any idea why?
PWA is here https://traact.app

have you tried just "start_url": "index.html" in the webmanifest.json that workaround made the chrome warning disappear for me.

@zedL
Copy link

@zedL zedL commented Mar 14, 2021 •

@pette9
I removed the "./" but unfortunatly this not change anything. The index.html file get not prefetched by the service worker.
https://traact.app/webmanifest.json

@asiiro
Copy link

@asiiro asiiro commented Mar 14, 2021

@gkalpak @pette9 I can confirm that after a number hours of trying, the start_url index.html workaround does not seem to work on any of my personal or work related apps. I've had varied success when testing over localhost, however, on a production environment with TLS I simply cannot bypass this warning. If this is working for you, make sure to not just look at the console, if you break service worker installation due to your testing, the warning will obviously not show because the PWA criteria will not be satisfied. At this point, I think I'm going to wait for an official fix, since as @clementcontet reports, which I can also confirm, the default template doesn't work anyway.

@tmtron
Copy link

@tmtron tmtron commented Mar 16, 2021

In the meantime, one workaround is to set your web manifest's start_url to something that will be in the cache (for example, index.html, which is by default part of an eagerly installed asset cache).

Thanks. Setting "start_url": "/index.html", worked for us.

@mdarefull
Copy link

@mdarefull mdarefull commented Mar 16, 2021

In the meantime, one workaround is to set your web manifest's start_url to something that will be in the cache (for example, index.html, which is by default part of an eagerly installed asset cache).

I can also confirm the workaround worked for me. I also modified the scope to be absolute "Just in Case".
This is how that portion of my manifest looks like now:
image
For everything else, I'm using the defaults.

AFAIK, I haven't detected any odd behavior by doing so. I've tested on localhost and our production environment as well.
One thing I've found useful to test this is to run the Lighthouse tool, without this fix, it was giving me a warning like:
image

But now there's no warning:
image

@gkalpak: Should we, at the very least, update the documentation to include this information asap? Is there any harm in updating the web manifest the schematics generate to this so that it becomes the new default?

@pette9
Copy link

@pette9 pette9 commented Mar 16, 2021

@gkalpak: Should we, at the very least, update the documentation to include this information asap? Is there any harm in updating the web manifest the schematics generate to this so that it becomes the new default?

Though the workaround worked in our case, this probably requires more investigation as @zedL and @asiiro have reported that it doesn't work on their applications.

@clementcontet
Copy link
Author

@clementcontet clementcontet commented Mar 16, 2021

Hi all, the workaround worked for me too.

@asiiro
Copy link

@asiiro asiiro commented Mar 16, 2021

Hi all, just an update from my end as well - I just re-tested this, and I'd like to confirm that @mdarefull solution works, however to add, it only works for me after clearing site data (but only certain projects are affected) - This is not ideal as users will not be doing this under a normal use case, but we can work with this for now. Thanks for the help all.

@zedL
Copy link

@zedL zedL commented Mar 16, 2021 •

even with @mdarefull suggestion it doesn't work for my application.

As far as I could understand it... after/during the first service worker installation the files from ngsw.json/assetGroups/0/urls not get all precached.
The files are listed there, but I can only see *.js files in the devtool network tab. I also had a look at the Cache Storage itself, no *.css or *.html are there.
Could it be that there is something wrong with the service worker itself? Shouldn't all listed files in the ngsw.json be preloaded and insert to the cache?

I will wait for an official solution.

@gkalpak
Copy link
Member

@gkalpak gkalpak commented Mar 16, 2021

Thx for the input, everyone 👍

@zedL, your's is a different issue. There is a hash mismatch that causes the SW to enter a degraded state (and not complete its initialization):

Driver state: EXISTING_CLIENTS_ONLY (Degraded due to: Hash mismatch (cacheBustedFetchFromNetwork): https://traact.app/app-service-worker.js: expected 80c3ba1e799e32215044faf97209174ffc6b30c6, got 7b84fbc74f08985389dc539bea5fe609b61c721f (after cache busting)

See #40049 (comment) for more info on what this error means.

(You can see this error at https://traact.app/ngsw/state. See also the ServiceWorker in production guide for more info on SW debugging APIs.)

I can't comment on other people's apps/issues without looking at the code.

The work-around described in #41085 (comment) should work, but slight modifications/additional configuration might be required based on your specific setup.

In any case, this is just a temporary work-around. A proper fix should be released soon.

@zedL
Copy link

@zedL zedL commented Mar 16, 2021

@gkalpak Yeah, I saw it too. I have all the time the problem for files that not get minified (json for example) that the hash calculation gets mismatched. I have no idea where this comes from, maybe something in the middle manipulates the files.
Unfortunatly the service worker stops prefetching the other files in the list, so my "index.html" never get cached.
Thanks, I know now in what direction I have to look.

@mdarefull
Copy link

@mdarefull mdarefull commented Mar 16, 2021

@zedL Is it possible that you modify any of those files after building the app? I'm asking because I was doing a JSON Token Replace on my release pipeline to replace environment settings and that was, obviously, invalidating the checksums... I know this has been a popular practice when using CI/CD tools...

@zedL
Copy link

@zedL zedL commented Mar 16, 2021

@mdarefull Currently I get it to work with simply negative comment the problematic files out in ngsw-config.json.

I have 3 problems that leads to an hash mismatch:

  • a) an index.html file that gets loaded dynamicly from a .net5 backend and delivered the SPA with an fallback route. (file loaded as string and delivered through the framework as response)
  • b) a javascirpt file app-service-worker.js (my own wrapper over the angular ngsw-worker.js for handling notificationclick event (push notification))
  • c) pure json i18n language files

The same characteristic for all the file are that they are not minified. I also dont use any post build pipe.
Currently I dont know where this comes from. I host the app in an azure webapp. Nothing special, but devil is in detail :) If you have any other tips, let me know.

@gkalpak
Copy link
Member

@gkalpak gkalpak commented Mar 16, 2021

I've heard of servers, proxies or CDNs doing such optimizations (e.g. minifying files before sending downstream), so that's worth looking into, @zedL.

@EltonFaust
Copy link

@EltonFaust EltonFaust commented Mar 18, 2021 •

@zedL

  • a) an index.html file that gets loaded dynamicly from a .net5 backend and delivered the SPA with an fallback route. (file loaded as string and delivered through the framework as response)

I was facing the same problem, dynamicly generating the index.html and the webmanifest files, and I found a solution, need some work but is working.

My solution was to dynamicly generate the ngsw.json file, by importing the ngsw.json file generated by angular and replacing the sha1 hashes for both files (index.html and webmanifest)

Ended up with something like that:

// response to route -> path-to/ngsw.json
$swData = json_decode(file_get_contents('path-to/original-ngsw.json'), true);

// render the resulting content
$indexContentRendered = '...file rendered';
$manifestContentRendered = '...file rendered';

$swData['hashTable']['path-to/index.html'] = sha1($indexContentRendered);
$swData['hashTable']['path-to/manifest.webmanifest'] = sha1($manifestContentRendered);

echo json_encode($swData);

PS: I know it's not .net, just an example how to solve the problem
PS 2: this solution only would be a problem if you are rendering the index.html content different for every request

@zedL
Copy link

@zedL zedL commented Mar 21, 2021

@EltonFaust Hey, great idea! Thanks for sharing, I will have a look into it.

@phil-w
Copy link

@phil-w phil-w commented Mar 21, 2021

Even switching my CDN off makes no difference. The start URL can be anything and the error is there, even if I can see the thing referenced in my pre-warmed cache. It fails. It does not say why. There's nothing in the network panel which helps. It's a secret. Is it a Google trick to burn programmer hours chasing non-existent problems?

MDN state: "Note: The start_url member is purely advisory..." My bold.

The only way I can get rid of this useless noise message is to remove the start_url completely from the manifest. That makes no difference to the operation of the site (on or offline) as far as I can see, but it gets rid of the console noise. It puts noise into the application/App manifest section of the dev tools, but although that's not strictly correct either (the start_url is absent, not "invalid", see above), it's clear enough what they're bitching about and more easily ignored.

@StPaulis
Copy link

@StPaulis StPaulis commented Mar 24, 2021

Any updates?

The start_url workaround make the warning go away but I find errors in my installed applications logs.
Can't load the HTML file.

@bilelz
Copy link

@bilelz bilelz commented Mar 26, 2021

It finally works on my side with this configuration

{
    "name": "POC PWA",
    "short_name": "poc-pwa",
    "theme_color": "#1976d2",
    "background_color": "#fafafa",
    "display": "standalone",
    "scope": "/poc-pwa/",
    "start_url": "index.html"
}

My site is hosted in the folder poc-pwa : "example.com/poc-pwa"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet