Is it possible to make an in-app button that triggers the PWA "Add to Home Screen" install banner?
Solution 1:
Chrome(or any PWA supporting browser) triggers the beforeinstallprompt event for Web app install banner, which you can catch and re-trigger in more appropriate time when you think user wont miss it/convinced about adding your site to home page. Starting Chrome version 68, catching beforeinstallprompt and handling the install prompt programmatically is mandatory and no banners will be shown automatically.
In case the user have missed the prompt/declined to add to home screen, the event can't be manually triggered by our code. This is intentionally left that way to avoid web pages annoying the users to repeatedly prompt the user for adding to home screen. Thinking of users perspective, this makes complete sense.
Yes, there are cases when user miss the option accidentally and he may not know of the browser menu option to "Add to home screen" and it would be nice for us to trigger the same again. But unfortunately, that's not an option. At lest for now and I personally don't see that changing much considering how developers can abuse if its left to the developers to prompt.
Alternate option: If the user have missed the install prompt or even chosen not to install it to home screen, give some time and when you think he is starting to like your site(based on conversions) you can show him a full page or half page Div popup kind of install instructions to add your site to home screen from browsers menu. It can have some images or Gif animation showing user how to add to home screen from the menu. With that, it should be self explanatory to most users, if not all.
Here is some code example for the same, which is iOS specific(look under #PROTIP 3).
As a bonus, you can show some promotions like discounts or added features when user add to home screen, which will convince user to do so. PWA has a way to find if the site is accessed form the home screen or browser.
For Development/testing: If you need this banner to come multiple times for dev/testing purpose, you can set the below flow in your Chrome for the same,
chrome://flags/#bypass-app-banner-engagement-checks
Solution 2:
Thanks for all the great answers. Recently it appears that things have become more standardized, and there is a solid way of doing things in chrome at least that allows users to click and install the app even if they missed the prompt etc.
Pete LePage wrote a very clear article on web.dev called How to provide your own in-app install experience which details the process. The code snippets and process is taken directly from the article.
- Listen for the
beforeinstallprompt
event.
let deferredPrompt;
window.addEventListener('beforeinstallprompt', (e) => {
// Prevent the mini-infobar from appearing on mobile
e.preventDefault();
// Stash the event so it can be triggered later.
deferredPrompt = e;
// Update UI notify the user they can install the PWA
showInstallPromotion();
});
- Save the beforeinstallprompt event, so it can be used to trigger the install flow later.
buttonInstall.addEventListener('click', (e) => {
// Hide the app provided install promotion
hideMyInstallPromotion();
// Show the install prompt
deferredPrompt.prompt();
// Wait for the user to respond to the prompt
deferredPrompt.userChoice.then((choiceResult) => {
if (choiceResult.outcome === 'accepted') {
console.log('User accepted the install prompt');
} else {
console.log('User dismissed the install prompt');
}
});
});
- Alert the user that your PWA is installable, and provide a button or other element to start the in-app installation flow.
For more details and other capabilities, see the full article.
I made a working demo of a this process implemented in React. (source code)
Also, for a slightly different approach, you can see how the maker(s) of Snapdrop implemented an install button in the source code.
Solution 3:
Well, there's nothing stopping you from storing the deferredPrompt value in a variable and use it later. Then you can popup a custom box, and if the user closes it down, you still haven't ran deferredPrompt.prompt() and can use it later. I store mine in Redux. If the user closes the install prompt, I use the deferredPrompt in the hamburger menu to install it at any time.
Listen to install and store event as prompt
const beforeInstallListener = e => {
// Prevent Chrome 76 and later from showing the install prompt
e.preventDefault();
// Stash the event so it can be triggered later.
dispatch(setAndroidDeferredPrompt(e));
dispatch(showAndroidPromptDownload(true));
};
window.addEventListener("beforeinstallprompt", beforeInstallListener);
Create a function which uses this deferredPrompt to prompt the user
const installToAndroid = async () => {
dispatch(showAndroidPromptDownload(false));
deferredPrompt.prompt(); // Wait for the user to respond to the prompt
const choiceResult = await deferredPrompt.userChoice;
if (choiceResult.outcome === "accepted") {
console.log("User accepted the PWA prompt");
} else {
closeAndroidPromptWithoutDownload();
console.log("User dismissed the PWA prompt");
}
dispatch(setAndroidDeferredPrompt(null));
};
Remember, if the user clicks the banner to install, deferredPrompt.prompt() is invoked and it won't work anymore. Therefore I keep a check to see if deferredPrompt exists, and remember to set it to null if the user has invoked .prompt().
{deferredPrompt && <button onClick={() => installPWA(deferredPrompt)}>Installer til hjemskjerm</button>}
This was done with React Hooks, Redux and LocalStorage (where I store a pwa.reducer.js state)
Solution 4:
In mobile Chrome on Android, "Add to Home Screen" can be accessed from the browser's menu. (Similar options may exist for mobile Safari/Firefox on Android/iOS as well.) The web app manifest file is read and the app is added as it would be with the original prompt feature.
While JavaScript cannot be used to manually invoke the prompt, a workaround would be to provide on-screen instructions showing users how to manually open the menu and add for their specific user-agent.
Solution 5:
There are events that browsers are now firing that help with the issue of handling installation of PWA's. It's not a web standard YET, but it's a good approach.
- 'beforeinstallprompt' is fired right before the prompt is shown and
- 'appinstalled' is fired right after the installation is complete.
So you can intercept 'beforeinstallprompt' event, prevent it from happening so that the banner doesn't show up, stash it for when you want the banner to show up, and finally create a button that a user clicks to then fire the earlier deferred event at will.
Below is a link about how to achieve this:
https://web.dev/installable/discover-installable/codelab-make-installable