Determining PWA installation status

I think you already know the answer to your question, you listed all the available APIs and Events with their cons, but you seem to be looking for a confirmation

So yes, there is no way to know with exactly a 100% certainty if a PWA is installed as there is no API for it

However the events you mentioned are complementary, so with a combination of them you can get pretty close

let isInstalled = localStorage.getItem('pwaInstalled') === '1' || false;

if (window.matchMedia('(display-mode: standalone)').matches || window.navigator.standalone === true) {
    // User is currently navigating on the PWA so yes it's installed
    localStorage.setItem('pwaInstalled', '1');
    isInstalled = true;
} else {
    //User is navigating in browser
    window.addEventListener('beforeinstallprompt', () => {
        localStorage.setItem('pwaInstalled', '0');
        isInstalled = false;
        //User can get an installation prompt meaning the app is not installed
    });
    window.addEventListener('onappinstalled', () => {
        localStorage.setItem('pwaInstalled', '1');
        isInstalled = true;
    });
}

Like this you have the flag pwaInstalled in local storage, telling you if the app is installed or not, if the data is cleared the flag will be lost but the next time the user visits either the PWA or the browser, this flag can be set correctly again into storage

If the user deletes the app and visits the browser the flag will be deleted

Note that the beforeinstallprompt event is experimental (pretty much like everything in PWA) it does not fire/exist in some browsers that do support the installation of PWA and may not be fully accurate in the others (some may fire it even if the app is already installed) It will also not fire for 90 days if the user has dismissed it

However, since to display the A2HS modal/button you are relying on the beforeinstallprompt event. It shouldn't matter if it doesn't fire, leaving only a problem if it fires when the PWA is already installed (I would suggest a test on all supported browsers with different android versions if you need to determine which ones don't)

In conclusion, assuming the beforeinstallprompt event fires accurately then you should have close to a 100% accuracy on whether the app is installed or not


You can check if the user is using the installed version
But as you mentioned, you would not know if they are using the browser version, and also have it installed

One thought
If not standalone AND beforeinstallprompt does NOT fire, then you may be able to assume it is installed and they are using the browser version.

Most likely, if installed most people will use that version.

In your code, check to see if the window is standalone

if (window.matchMedia('(display-mode: standalone)').matches) {  
    // do things here  
    // set a variable to be used when calling something  
    // e.g. call Google Analytics to track standalone use   
}