Over a million developers have joined DZone.

Mobile Deep Linking for Web and Hybrid Apps

DZone 's Guide to

Mobile Deep Linking for Web and Hybrid Apps

· Java Zone ·
Free Resource

Written by Tim Severien for Telerik Mobile Blog.


Every now and then, new statistics pop up confirming that an ever growing proportion of online traffic originates from mobile devices. The HTML5 specification reflects this, as the spec has been stuffed with APIs that allow web applications to use hardware commonly found in mobile devices. Browsers also implement operating system specific links – for instance, when you browse for an image, instead of a plain file browser, you get to choose between using your device photos app or camera.

Another one of the features geared primarily towards mobile traffic is deep linking, a primitive form of interaction allowing one app to open another, ideally at a specific view or state. For example, this would allow you to directly show a product in a shopping app or prepare a predefined message in your favorite messaging app, which can mean a major improvement to your app’s overall user experience!

Ina Toncheva explains more about deep linking in Why Mobile Developers Should Care about Deep Linking.

Basic usage

Deep linking is quite similar to regular links to URLs, but instead of linking to a standard browser URL, we link to a specific URL that is reserved and handled by an app.

We have had this on the desktop for ages. For example, the game platform Steam has reserved a custom protocol (steam://) to open things in the Steam client instead of a web browser. However, this article focuses on mobile web usage.

A link that opens WhatsApp would look like this:

<a href="whatsapp://app">Open WhatsApp</a>
<a href="whatsapp://send?text=Hello%20World">Send "Hello World" via WhatsApp</a>

As these links are app-specific, you will have to look them up for the particular app you may be interested in. GotSchemes is one of the most complete and accurate resources I could find to locate this information.

That’s all there is. Thank you for reading this article!

…Still here? Good, because we’re not actually done yet.

Problems – and how to overcome them

As simple as it seems, there are a few things we have to consider.

  • Is the application installed on the client?
  • Has the device executed the deep link correctly?
  • Is it possible to accurately detect all of the above?

The answer to these questions is: No, we can’t; not accurately that is. There is no such thing as a “Detect Client Software API,” and with good reason, I might add. I wouldn’t want a malicious site to look at what apps I run. Unfortunately, that does makes it difficult for us to implement a stable link.

Unlike the web, apps do not magically run on all platforms. A widely deployed app only works on a handful of operation systems. We can detect whether a client supports the apps by simply checking what OS the client is running, usually called “OS sniffing.” With that information, we can already determine if the client supports apps or not. Today, Android and iOS own roughly 92% of the market, so let’s focus on just these two for now.

Here’s an example of how to hide a link if the OS is not supported:

// If user agent does not meet criteria...
if(!navigator.userAgent.match(/iPhone|iPad|iPod|Android/i)) {
    // Get elements
    var links = document.querySelectorAll('a.mobile-deep-link');

    // Hide all the elements!
    Array.prototype.forEach.call(links, function(el) {
        el.style.display = 'none';

Detecting if a link actually works is difficult. There are no events for this. When a link works, the user leaves the pages; something we can detect. If the user has not within a period of time, we redirect the browser to that app in the Play or App store. Sounds simple, right?

Using the Page Visibility API, we can detect whether a user is viewing the page. This API is in an early stages of development and has limited browser support. Luckily, Addy Osmani created Visibly.js, a sort of polyfill for the Page Visibility API, that uses focus and blur events as fallback.

By storing the fallback URLs in the DOM element, they can easily be referred to individually.

<a href="whatsapp://whatsapp?text=Hello%20World"
Say “Hello World” on WhatsApp!

First we detect the the Operation System by sniffing the User Agent string and detect if the OS supports mobile deep links. If so, all elements get a click handler in which we test whether a link has worked or not. If not, it opens the given URL of one of the attributes for that OS.

var links,
    os = {
        android: navigator.userAgent.match(/Android/i),
        ios:     navigator.userAgent.match(/iPhone|iPad|iPod/i)

if(os.android || os.ios) {
    links = document.querySelectorAll('[data-store-android], [data-store-ios]');

    // Iterate through elements
    Array.prototype.forEach.call(links, function(el) {
        // Do something when link is clicked
        el.onclick = function() {
            var button = el,
                delay = 1000,
                start = new Date().getTime();

            // Start the timeout
            setTimeout(function() {
                var end = new Date().getTime();

                // Check if the page is visible
                // If this timeout is triggered after 2 * delay,
                // it's likely the user went away, the browser
                // didn't fire a blur event or alike and paused JS from executing
                // which means the link probably worked
                    visibly.hidden() ||
                    now - start >= delay * 2
                ) return;

                // Get shop URL
                var shop = os.android ? button.dataset.storeAndroid : button.dataset.storeIos;
                window.location.href = shop;
            }, delay);

Unfortunately, some browsers on Android appear to open the app without triggering a blur-like event nor pausing the code, resulting in the Play Store opening regardless, which can be somewhat annoying to your user.

All of this packed in a tool called deep-link.js, which is dedicated to providing an easy way to add deep links and to continuing the search for stable support.

Is the web ready for mobile deep links?

Using regular HTTP-links that can be opened by an app is the best choice by far, as seen on apps like Youtube and Ebay. However, provided the fixes above, support for custom schemes is pretty stable, though not perfect. Using deep links and the “hacks” described above should be a conscious consideration.

Ideally, all apps should handle regular URLs and serve the same content in the same manner for all platforms – but that’s never happening. Instead, vendors need to help by making cross-platform, mobile deep linking easier. Until then, we’ll have to be content running on some variation of this hack. But don’t many great things on the web platform seem to start with hacks?

Header image courtesy of gfpeck.


Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}