Open an app (iOS/Android) via JavaScript, with a fallback redirect to App/Play store (2016 edition)

22,085

Solution 1

In 2016, this is impossible to achieve via Javascript alone

You can still use the approach on Android, but Apple made changes in iOS 9.2 that mean this is essentially useless on iOS devices.


How it used to work on iOS

The way this was done in the past was to attempt to open up the app in Javascript by setting window.location to the custom URI path that you wanted.

window.location = “imdb://title/tt3569230”;

App not installed

The problem with this is that when the app is not installed, it shows a ‘Cannot Open Page’ error. I’m sure you’ve all seen it. It’s the bane of deep linking. There was a glorious period during iOS 7 and iOS 8 where it was possible to bypass this, but the golden age has passed.

In order to avoid this, you had to add some Javascript to your page where you would redirect away to the App Store. This way, the user was not left with an error on the screen.

window.location = 'imdb://title/tt3569230';
setTimeout(function() {
  window.location = 'itms-apps://itunes.apple.com/us/app/imdb-movies-tv/id342792525'
}, 250);

App installed

When the app was installed, it would display the modal below, prompting the user if they want to open the app:

What happens now is that in iOS 9, Apple changed the Open in "[app]" modal from a Javascript blocking modal to a non-blocking modal. This means when you try to open up the app via a Javascript redirect to a custom URI scheme, the modal will no longer block Javascript from executing, with the result that the fallback redirect to the App Store will execute immediately before the user can tap the 'Open' button.

At Branch.io (full disclosure: I'm on the Branch team), we saw this coming in the iOS 9.2 betas and were hopeful that our Apple radars (bug reports) and influential partners could motivate Apple to resolve it before release. Unfortunately for iOS developers, it was not to be. Apple’s response to our concerns made perfectly clear what they wanted everyone to do: adopt Universal Links.


Solution for 2016

The only way to have a single link that works everywhere (including routing into apps if they are installed or to fallback web URLs if they are not) must include using Universal Links on iOS. Of course, Universal Links aren't actually supported everywhere in iOS yet, so there are specific edge cases where custom URI schemes are still required (Chrome and Gmail being two big examples). You'll need to detect these and build custom handling.

Most companies don't have the resources to devote a full-time engineer (or two) to this, which is why Pinterest, Tinder, Airbnb, Jet.com, Yummly, etc., have all adopted linking platforms like Branch.io or Firebase Dynamic Links.

Solution 2

So the way it works on ios without always opening the store when the app is installed is to do something like this:

function isIOS() {
    const iDevices = [
        'iPad Simulator',
        'iPhone Simulator',
        'iPod Simulator',
        'iPad',
        'iPhone',
        'iPod'
    ];

    if (navigator.platform) {
        while (iDevices.length) {
            if (navigator.platform === iDevices.pop()) {
                return true;
            }
        }
    }

    return false;
}

let openedApp = false;

function openAppOrStore() {
    setTimeout(function () {
        if (!openedApp) {
            window.location = "https://apps.apple.com/us/app/petleo/id1462882016";
        }
    }, 25);
    const parts = window.location.href.split('/');
    const consultationId = parts[parts.length - 2];
    const iosLink = "petleo://consultations/" + consultationId;
    try {
        window.location = iosLink;
        if (window.location.href.indexOf("petleo://") !== -1) {
            openedApp = true;
        }
    } catch (e) {   
    }
}

setTimeout(function () {
    if (window.location.href.indexOf('consultation') !== -1) {
        if (isIOS()) {
            openAppOrStore();
        }
    }
}, 25);
Share:
22,085
Max
Author by

Max

Making the world a better place

Updated on May 31, 2020

Comments

  • Max
    Max almost 4 years

    Given: Website, iOS and Android applications, registered urlscheme "myapp://".

    Goal: on the website have a link shown to iOS/Android devices with app installed. Clicking on that link should open the app and invoke specific logic (handled by the app, essentially like "universal links" from apple, but without shadowing website links).

    Due to security constraints detecting if an app is installed is troublesome without webview cookie magic. Given that, what would be the best approach to try and open an app via JavaScript, and invoke a fallback redirect if that fails?

    Solution from this thread: Is it possible to register a http+domain-based URL Scheme for iPhone apps, like YouTube and Maps? doesn't work with iOS10. Not sure about Android.

  • Groben
    Groben over 6 years
    I know I'm doing the archeologist here but what if I just want a fallback on a facebook deeplink ? I'm doing a small website and Branch.io seems like overkill for it. I just need a deeplink on a facebook profile and one on an instagram profile. Is it on me to implement fallback ?
  • Alex Bauer
    Alex Bauer over 6 years
    @Groben Branch is designed for your own app. It wouldn't work for linking into Facebook and Instagram, so yes...you'd need to build that redirect yourself!
  • zaitsman
    zaitsman over 3 years
    So on iOS 14 it runs into the issue described by @AlexBauer where if the app is installed, Safari STILL redirects the user to App store, just 25 ms later.