How to intercept app install prompt in Angular PWA?
Asked Answered
T

2

6

I have created a PWA using Angular guidelines. I am facing problem intercepting the app install banner. I am using this code to defer it to a later point:

let deferredPrompt;
window.addEventListener('beforeinstallprompt', (e) => {
  // Prevent Chrome 67 and earlier from automatically showing the prompt
  e.preventDefault();
  // Stash the event so it can be triggered later.
  deferredPrompt = e;
  console.log("Intercepting the app install banner prompt");

  setTimeout(function() {
    deferredPrompt.prompt();
  }, 20000);

  // Wait for the user to respond to the prompt
  deferredPrompt.userChoice
  .then((choiceResult) => {
    if (choiceResult.outcome === 'accepted') {
      console.log('User accepted the A2HS prompt');
    } else {
      console.log('User dismissed the A2HS prompt');
    }
    deferredPrompt = null;
  });
});

My manifest file:

{
  "name": "TreadWill",
  "short_name": "TreadWill",
  "theme_color": "#2a3b3d",
  "background_color": "#2a3b3d",
  "display": "standalone",
  "scope": "/",
  "start_url": "/",
  "icons": [
    {
      "src": "assets/icons/icon-72x72.png",
      "sizes": "72x72",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-96x96.png",
      "sizes": "96x96",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-128x128.png",
      "sizes": "128x128",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-144x144.png",
      "sizes": "144x144",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-152x152.png",
      "sizes": "152x152",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-384x384.png",
      "sizes": "384x384",
      "type": "image/png"
    },
    {
      "src": "assets/icons/icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ]
}

When I try this code in localhost, the message included in the console.log is getting logged but after 20 seconds, I am getting an error:

Uncaught (in promise) DOMException

in this line:

deferredPrompt.prompt();

When I host the code and try it on mobile, the app install banner shows up instantly instead of after 20 seconds.

I have tried putting this code in the index.html file itself, in a separate js file and calling that in the index.html file. Creating a service and including almost similar code in a .ts file. Nothing has worked. Although I am trying out js solutions out of desperation, I would prefer Angular solutions to the problem. Ideally, I would like to catch and store the 'beforeinstallprompt' event in a global variable and prompt the event at different points.

How to solve this problem?

Tallou answered 13/2, 2019 at 15:10 Comment(2)
This is chrome? Currently, in Chrome is a temporary solution there where the install banner shows if your app has all the proper things no matter what you do. Ultimately (I believe) the plan is to let you control the install. But not now.Saundra
@Saundra Yes, it is chrome. Thanks for letting me know. But from this official guide developers.google.com/web/fundamentals/app-install-banners I got the impression that I should be able to defer it to a later point.Tallou
S
5

You are probably doing it properly, but according to this article:
"The mini-infobar will appear when the site meets the add to home screen criteria, regardless of whether you preventDefault() on the beforeinstallprompt event or not."
So for me also, it shows immediately.

Pete LePage (@petele) is a good person to follow on twitter for updates to A2HS.

Here is the Add To Home Screen (A2HS) tester I built. There is a link to the source code on the bottom of the page. Feel free to use anything that may be helpful. I have not updated it recently to the most current version of angular. But it should all still work fine since it's basic code.
https://a2hs.glitch.me

Saundra answered 16/2, 2019 at 12:47 Comment(0)
T
4

The links provided in Mathias' answer helped me solve the problem. I am just adding a few points that are not explicitly mentioned in the answer but might help someone else.

  • The app install banner can only be shown on some user activity. For example - a button click. It can't be prompted via setTimeout.
  • Currently, intercepting the beforeinstallprompt and showing it later works in Chrome and Edge because Chrome and Edge fires the event automatically when the user visits the site. Firefox doesn't fire the beforeinstallprompt event and hence it doesn't work on Firefox.
Tallou answered 17/2, 2019 at 9:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.