The Progressive Web Application Add to Homescreen Library Abstracts Browser and Platform Differences Away

Add to Homescreen Library
Add to Homescreen Library

Business owners and online marketers tend to measure their Progressive Web App success by homescreen adoption. I don't blame them, it is a clear sign the consumer wants a deeper relationship with the brand.

The good news is I created a library and tool to help you craft an add to homescreen experience that should help you earn a spot on your visitor's homescreen.

To be fair I did not create the library from scratch, but I forked Matteo Spinnelli's old Add to Homescreen library. I used this library for years to prompt on iOS. Since then Progressive Web Apps have happened and it seems Matteo has moved on from software development.

Since something needed to be done I decided to start with his library and upgrade it.

The goal of the Love2Dev AddtoHomescreen prompt manager is to put you in control of the experience. It leverages the native prompt when available, but also provides guidance when native prompts are not available.

The main goal is to abstract as much of the platform differences away to give you a consistent way to manage the experience.

Clients have asked me to control prompting users to install the PWA using a variety of rules. The library has been designed to allow flexibility when it comes to applying your ruleset.

While having a user add your PWA to their homescreen or desktop is an important metric to measure your site's engagement success it is not the only metric.

But let's focus on it anyway!

What is Add to Homescreen?

If you follow modern best practices and leverage minimum PWA requirements your application offers the user experience benefits, even if the customer has not added the site to their homescreen or desktop.

With that being said, I am like everyone else, I want that icon on my visitor's homescreens.

On Android, PWAs installed from Chrome are magically converted to a WebAPK. This is a technical term for saying the PWA is transprently packaged as a native Android app with out being a full blown app. You get app shelf and other benefits as well as the coveted homescreen icon presence.

On Windows, its not a homescreen per se, you get a spot in the start menu as well as a desktop icon. The installed instance of the PWA can also be uninstalled using the Windows unintall process, just like any other application.

So how can you earn that coveted placement on the user's device?

There is no single answer to that puzzle. There are technical requirements, which are controlled by individual browsers. These we can handle, with some finesse.

Of course, the more difficult part is coaxing the visitor to install the progressive web app. That is where your app needs to be compelling, providing enough value for them to justify adding the site to their homescreen.

Unfortunately the Add to Homescreen library won't help with building the trust with the customer, that is still up to you.

Back to the technical. Browser and platform vendors have not made it very simple to manage. The install process is still a bit wild at this time.

While there is an official specification for the web manifest, it leaves it open to browsers as to how they will handle the add to homescreen experience.

While the spec details how a native prompt can be managed via client-side JavaScript by wiring an event handler to the beforeinstallprompt event.

The actual user prompt flow and prompting is left open ended.

Today, Chrome and the new Edge are the only two browsers implementing the beforeinstallprompt event.

Safari has yet to implement support for the web manifest, which means we still need to lean on the original, 2007 era, iOS plumbing to earn that Progressive Web App homescreen icon on an iPhone.

Other browsers just display a little icon in the browser's omnibox to indicate the site can be installed, if anything at all.

It is these variations in how a user is prompted by the browser and the actual process to install a PWA that lead to frustration. And don't think Chrome and new Edge have things figured out, they don't.

It’s frustrating with Chrome because it seems they are continually tinkering with the experience. Last year, for example, you could just bind to the beforeinstallprompt event and prompt the user. That has changed and now the user must initiate the prompt, like from a click event, and then you can trigger the actual prompt.

As you can see the variations are all over the place. So, it is left up to you, the site owner, developer and designer to create a consistent add to homescreen prompt experience.

It is these variations that prompted me to design this library to abstract the differences away as much as possible.

Now to review how to the library works, how to use it on your site.

How the Add to Homescreen Manager Works

Before I do that, you can always use our PWA Starter to walk you through the process of configuring the library to make it easy to inject on your website as well as other PWA support files.

First, let's look at how different browsers implement the add to homescreen experience.

Chrome and New Edge

The Chromium project has the best progressive web application homescreen prompt mechanism, the beforeinstallprompt event and a native prompt banner.

Right now the only browsers supporting this feature are Chrome and the new Edge. I keep hoping other browsers will ship support for this native event, but for now it is limited.

I love there is a native prompt, the problem is it seems Google keeps changing the user experience around the install prompt. The main thing to remember is the beforeinstallprompt event will trigger if the browser determines the site meets its minimal PWA requirements.

Of course each browser determines its own criteria of what exactly are the minimum PWA and PWA installability requirements.

The way the prompt is supposed to work is you capture the event and keep it from triggering until you want it to prompt the user.

var _beforeInstallPrompt;

if ( "onbeforeinstallprompt" in window ) {

	window.addEventListener( "beforeinstallprompt", beforeInstallPrompt );


function beforeInstallPrompt( evt ) {


	_beforeInstallPrompt = evt;


In this code example a feature dection is made to see if the beforeinstallprompt event is supported. If it is then an event handler is created on the window object.

If the site meets the minum criteria the event will trigger according to the browser prompting heuristics.

Beware, just because the event fires does not mean the prompt will trigger. The published rule requires the prompt to be displayed in response to a user action. This means the user should click a button or some other action.

Because the Add to Homescreen library controls the display on an initial banner prompt or possibly other page elements, like a menu option etc, you are covered for the user gesture requirement.

Prompting the User Natively

After you have captured the native prompt, you need to trigger that actual user prompt. To do this you must call the 'prompt' method on the event object you captured. It returns a promise and resolves a value to let you know what the user chose.

return _beforeInstallPrompt.prompt()
   .then( function ( evt ) {

      // Wait for the user to respond to the prompt
      return _beforeInstallPrompt.userChoice;

   } )
   .then( function ( choiceResult ) {

      //do stuff here
   } )
   .catch( function ( err ) {

      if ( err.message.indexOf( "user gesture" ) > -1 ) {
         //recycle, but make sure there is a user gesture involved
      } else if ( err.message.indexOf( "The app is already installed" ) > -1 ) {
         //the app is installed, no need to prompt, but you may need to log or update state values
      } else {
         return err;

   } );

The prompt method does not always resolve, it may throw an exception, which you need to catch.

In the example above I capture the two most common errors, user gesture required or the app is already installed. Exceptions are thrown because the ability to display the native prompt failed.

Example Native Add to Homescreen Prompt
Example Native Add to Homescreen Prompt

If this sounds confusing, don't worry, the Add to Homescreen library abstracts all this away so you don't need to worry about handling all the plumbing.

If the browser supports beforeinstallprompt when the user choses to install the application from the A2HS prompt the native prompt will be displayed.

And don't worry, we have you covered for other browsers too, like iOS.

How You Can Add a Progressive Web App to your iPhone or iPad Homescreen

Apple of course was the first to the modern mobile world. When they released the iPhone the original app strategy was HTML5 apps you added to the homescreen.

Since then Apple has supported this add to homescreen installation flow with touch icons and the ability to open installed web apps full screen.

The real issue with the experience is they never added any native prompting experience. Instead the user has to walk through a collection of steps to install the application.

  • Open up Safari and load a web site.
  • At the bottom of the screen is the share icon [insert icon here]. It is an arrow pointing up from a square.
  • At this point the share sheet is rendering. You will need to slide the icons to the left to reveal the 'Add to Homescreen' button.
  • You'll be asked to choose a name for the homescreen icon. So, you know, pick a good one and save it. When you're done it'll show up on your homescreen and you'll never have to type in that stupid URL ever again.

Even though there is no native prompt available on iOS you can still use the existing 'plumbing'. The Add to Homescreen library will still trigger a prompt just like the beforeinstallprompt experience.

iOS A2HS Process
iOS A2HS Process

Instead of displaying the native prompt, which of course is not available, a set of screenshots will animate to help educate the user on how to add the site to their homescreen.

The user will still need to walk through the process, unfortunately there is no way to programmatically install the site to their homescreen.

Safari is the only iOS browser. So other browsers don't come into play, but again the library abstracts you away from the difference.

You can customize the images and steps that are displayed to guide the user through the process.

FireFox, Opera, Samsung and other browsers

Last, the other browsers. Other than Chrome and the new Edge most browsers don't really support an add to desktop on laptops, so the add to homescreen experience in other browsers is largely limited to Android.

Firefox Add to Homescreen Confirmation
Firefox Add to Homescreen Confirmation

Right now, these browsers don't support the beforeinstallprompt, so the experience is sort of like iOS, manual.

So I borrowed from the iOS prompting experience. The library detects the different platforms/browsers and will trigger an image or sequence of images to guide the user to the menu item or omnibox trigger to add the PWA to the homescreen.

Configuring Your Rules

After abstracting the platform differences away, the next awesome Add to Homescreen Manager feature is providing a multifaceted configuration to control when and where the prompt is triggered.

I have had clients ask to control when the user is prompted. Some want the prompt gated behind the first login or a number of page views or even in response to a specific action on the site.

You also want to avoid interrupting the user in a critical flow, like purchasing a product.

The point is there is no one set of rules to control how a prompt is triggered. This meant I needed to think of as many scenarios as possible and provide a way to apply rules as simply as possible.

I think I have added properties that can be set to manage the majority of scenarios. However, there is a property that can be set to a custom business rule or true|false value.

You cna think of this as your way to extend the browsers minimum requirements.

The library has all sorts of configuration options and all scenarios must be met before the prompt will display.

  • mandatory: you can't proceed if you don't add the app to the homescreen
  • autostart: show the message automatically
  • skipFirstVisit: show only to returning visitors (ie: skip the first time you visit)
  • minSessions: show only after minimum number of page views
  • startDelay: display the message after that many seconds from page load
  • lifespan: life of the message in seconds
  • displayPace: 1440, minutes before the message is shown again (0: display every time, default 24 hours)
  • displayNextPrime: A fun 'algorithm' I added to trigger the prompt based on page views that are prime numbers
  • customCriteria: A hook for you to provide either a custom method or a simple true|false value to control when it prompts

The following code is just one example of how the library can be configured. You execute the library by calling addToHomescreen as a function, passing an object with your configuration values.

var ath = addToHomescreen( {
    autostart: false,
    autoHide: 0,
    logging: true,
    minSessions: 2,
    onShow: function () {
        console.log( "showing" );
    onInit: function () {
        console.log( "initializing" );
    onAdd: function () {
        console.log( "adding" );
    onInstall: function () {
        console.log( "Installing" );
    onCancel: function () {
        console.log( "Cancelling" );
    displayNextPrime: true,
    customCriteria: true,
    displayPace: 0,
    mustShowCustomPrompt: false,
    customPrompt: {
        title: "custom message",
        src: "",
        cancelMsg: "go away",
        installMsg: "do it"
} );

I have tried to include a series of demonstrations in the source code repository. One thing I embedded in the library is the ability to set the device type and even force a prompt by setting debug to true.

If you are trying to test your logic I recommend you tinker with these settings because you will need to verify the desired experience happens on different platforms. Debugging across all the browsers and platforms can be frustrating, especially iOS.

Because I realized there was no way to account for every case a site might need to leverage I added a customCriteria property. This can be either a method or a Boolean value. This is your way to create your own logic to control the install banner display.

var ath = addToHomescreen( {
    customCriteria: yourCustomCriteriaHere // this could be a function or a value. 
} );

The value or method result must be either true or false. The library only checks if the value it true, which is the default setting.

Another set of 'hooks' I added were some events. For example, onInit, onAdd, etc. This allows you to inject code into the prompt workflow. A common use of this would be to log the user's choice in response to the prompt. I used them a lot as part of my development process, so feel free to do that as well.

var ath = addToHomescreen( {
    onShow: function () {
        console.log( "showing" );
    onInit: function () {
        console.log( "initializing" );
    onAdd: function () {
        console.log( "adding" );
    onInstall: function () {
        console.log( "Installing" );
    onCancel: function () {
        console.log( "Cancelling" );
} );

The library will fall through a series of checks based on these settings to determine if the prompt can be displayed and how long it will wait to display after all the checks pass.

Now that you have customized the prompting logic you will need to customize the actual prompt.

Customizing the Add to Homescreen Prompt

The standard way we have been trained to prompt a user to install a progressive web app is to display a banner either at the bottom or top of the view port. And to be honest this is how I designed the library experience, but you don't need to limit yourself to a banner.

Add to Homescreen Library Example Prompt
Add to Homescreen Library Example Prompt

You could also show and hide an inline message, sort of like an add within your content. You could also add it to a menu or maybe on a configuration or settings page.

Because there are many scenarios to display a message to the user you can configure the library how you need.

By default I assume a few custom CSS class names as hooks to select target elements. You can change those classes through the configuration, just like you can the prompting logic.

athWrapper: ".ath-container",
athGuidance: "ath-guidance",
showClasses: [ "animated", "d-flex" ],
showClass: "d-flex",   
hideClass: "d-none",
promptDlg: {
   title: ".ath-banner-title",
   body: ".ath-banner",
   logo: ".ath-prompt-logo",
   cancel: ".btn-cancel",
   install: ".btn-install",
   action: {
      "ok": "Install",
      "cancel": "Not Now"

Notice how the athWrapper property is a CSS selector, not just a class name. This makes it flexible so you can use multiple items on the page with different class identifiers.

athWrapper: ".ath-container, .ath-menu-item"

The elements desginated with this selector should be the outermost element, with the actual prompt markup housed within it's scope.

<div class="ath-container banner-bottom-center">
    <div class="ath-banner">
        <div class="ath-banner-cell ath-banner-cell-md">
            <img src="imgs/pwa-logo-50x50.png" alt="PWA" class="ath-prompt-logo">
        <div class="ath-banner-cell">
            <button class="btn btn-cancel btn-link">Not Now</button>
        <div class="ath-banner-title">
            <p>Install this PWA?</p>
        <div class="ath-banner-cell">
            <button class="btn btn-install btn-success">Install</button>

This is the 'default' markup I designed the experience around. You can set the content of each of the cells, including the logo. The library will look for these classes to replace text, etc based on how you customize the prompt.

This is done through the customPrompt property. It is a JavaScript object where you can tweak the prompt resources.

customPrompt: {
    title: "custom message",
    src: "meta/android/android-launchericon-48-48.png",
    cancelMsg: "go away",
    installMsg: "do it"

Right now I have not made it flexible enough to support multiple languages, this is a higher priority on the todo list.

Now the banner is customized you will need to customize your platform prompts.

Customizing the Guidance

The customization does not stop with the banner and when the prompt is triggered. You can also customize the content used to guide the user through their platform's install process.

I wont go through all the platform configurations, because they all work in the same fashion. I will focus on the iPhone because the default setup I use has multiple images.

prompt: {
   "iphone": {
      targetUrl: undefined,
      showClasses: [ "iphone-wrapper", "animated", "fadeIn", "d-block" ],
      imgs: [ {
         src: "imgs/ios-safari-share-button-highlight.jpg",
         alt: "Tap the Share Icon"
         src: "imgs/iphone-a2hs-swipe-to-right.jpg",
         classes: [ "animated", "fadeIn", "overlay-1", "delay-2s"],
         alt: "Swipe to the right"
         src: "imgs/iphone-a2hs-icon-highlight.jpg",
         classes: [ "animated", "fadeIn", "overlay-2", "delay-4s"],
         alt: "Tap the Add to Homescreen Icon"

The targetUrl property can be set to the URL with full instructions instead of a simple image. Some sites want the give the user more detailed instructions, so this gives them the option.

The showClasses property is an array of CSS selectors used to show and hide the guidance.

The imgs property is an array of image objects. They are displayed in succession. If there is only one image it will be the only image displayed. If there are multiple images they will display one after the other using CSS animations.

The classes property is an array of CSS class names you can supply to control how the animation is applied.

Last the alt property is the value for the image alt attribute and used for accessibility.

When you clone or download the Add to Homescreen library these assets are included, so you don't need to go currate them yourself.

However, you are more than welcome to create your own images. For example if you wanted to trigger animated gif, illustration or even a video tutorial you could use those as well.


The goal is to control how you prompt and tease your visitors to add your progressive web app to their homescreen. Instead of putting this responsibility on you or your developer's shoulders the Add to Homescreen library provides a controlled mechanism to abstract away platform differences.

While each browser seems to require a different process for users to add Progressive Web Apps to their homescreen or deskopt you should not be intimidated by this. Instead you can use this library to give you a more common interface to handle these scenarios.

Hopefully this library can be reduced if all browsers would support the beforeinstallprompt event. You will still need to control when the prompt is displayed of course. So the PWA Add to Homescreen library will always have its place in everyone's Progressive Web App journey.

Share This Article With Your Friends!

Googles Ads Facebook Pixel Bing Pixel LinkedIn Pixel