In the mobile world, deep linking is a technology that launches an app and opens a specific page once a user clicks a URL on a web page or in another app. We will dive into the details of implementing deep linking for your app in this article.
Why do you need deep linking?
Let’s assume you’ve published a music app. To celebrate the release of a new song, you’ve paid tons of money to run a campaign on a popular website. In your campaign, you feature a brief sample of the song – and you probably want the user to listen to the sample inside of your app rather than on your website, where they would only see the album cover. In another example, let’s say you want to regain inactive users through a sales campaign. In this campaign, users would be directed to the sale products page in your app with a single click, without having to search for it or manually type a coupon code. This is where deep links come into play: in both examples, deep linking makes these campaigns possible.
In short, deep linking brings seamless user experience and can increase your conversion rate and retention rate significantly. More information on the effects of deep linking in campaigns can be found on our company blog.
How do you implement deep links?
I won’t dive into how to implement deep links. Both scheme-based deep linking (Android and iOS) and iOS 9+ Universal Link are fully documented. The basic ideas are quite similar: associate a URL (scheme based youapp://
or universal link https://yourdomain.com/
) with your app and when the URL is clicked, the system will open the app if it’s installed.
But the world isn’t perfect
You’re probably wondering, “What if someone clicks on a deep link URL but doesn’t have the app installed?” Unfortunately, they’ll either see an error message or nothing will happen. This is the problem we’re going to discuss in this article.
Deep Links for Android
Let’s assume your deep link URL is yourapp://path/
, and your App’s bundle ID is com.yourapp.example
.
JavaScript solution
A common and old technique to solve this problem is using iframe
to load the deep link URL and having a delayed JavaScript to redirect to store:
1 2 3 4 5 6 7 8 |
|
By doing this, the browser will try to load yourapp://path/
first.
- If your app is installed, then it will be opened and the following JavaScript won’t run.
- If your app is not installed, then nothing will happen while loading
yourapp://path/
. After 2 seconds, the page will be redirected by the JavaScript to to the Play Store, and the user can install the app from there.
The above code has a little problem, though – after the app is opened and the user switches back to their browser, the JavaScript may continue and redirect them back to the Play Store. So we can do some optimization by checking the time a user switches back to their browser in order to determine whether they need to be redirected to the store or not:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
|
Intent solution
Since Chrome for Android version 25 and later, the above code stopped working according to Chrome documentation. Fortunately, Google provides theIntent
URL for a better solution. When a user clicks on the URL intent://path/#Intent;scheme=yourapp;package=com.yourapp.example;end
, then
- if the app is installed, it will be opened by Chrome.
- if the app is not installed, Chrome will open Play Store.
Which solution should I use?
The Intent solution is highly recommended because it’s much simpler to implement and the user experience is more seamless. However, it requires browser support, and the Android system is unfortunately so fragmented that there are still plenty old OSes and browsers out there. Moreover, the Android WebView used by tons of apps don’t support Intent
URLs by default. The following table shows which solution you should use for mainstream Android browsers:
Browser | JavaScript | Intent | |
---|---|---|---|
Chrome 24 or below | √ | ||
Chrome 25 or above | √ | ||
Firefox | √ | ||
Android Browser | √ | ||
Facebook in-app Browser | √ | ||
Twitter in-app Browser | √ | ||
Other Browsers | √ |
Deep links for iOS
Assuming your deep link URL is yourapp://path/
and your app ID in app Store is 12345678
.
JavaScript solution
Similar to Android, there is also a JavaScript trick for iOS:
1 2 3 4 5 6 |
|
- if the app is installed, the first relocation code will open the app and the following script won’t run.
- if the app is not installed, the first relocation code will do nothing and the timeout function will redirect to App Store.
But as we discovered, this script works well in iOS 8 or below with Safari but doesn’t always work with other versions. Here is the table:
Browser | JavaScript | |
---|---|---|
iOS 8 or below Safari | √ | |
iOS Chrome | √ | |
iOS 8 Facebook in-app Browser | √ * | |
iOS 8 Twitter in-app Browser | ||
iOS 9 or above |
* partially working depends on Facebook app Version
Universal link solution
Starting with iOS 9, Apple published the universal link, which works similar to Android’s Intent
but requires more setup. And moreover, since iOS 9.2, the JavaScript solution stopped working since Apple made the prompt window non-modal. You can read more about this here.
In order to enable universal links, you need to have a SSL certificated domain (https://yourdomain.com/
, for example) associated with your app, and to serve a special JSON file under https://yourdomain.com/apple-app-site-association
similar to:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
|
This file tells your device which path serves as deep link for which app.
Then, in XCode you need to enter applinks:yourdomain.com
in your com.apple.developer.associated-domains
entitlement . One domain can be associated with multiple apps and vice versa.
Next, you need to adopt the UIApplicationDelegate
methods for Handoff (specifically application:continueUserActivity:restorationHandler:
) so that your app can receive a link and handle it appropriately.
Let’s assume you associate https://yourdomain.com/dress/*
with your app by setting "paths": [ "/dress/*"]
in the JSON file. When user clicks the link https://yourdomain.com/dress/1
in Safari,
- if the app is installed, your app will be opened and
https://yourdomain.com/dress/1
will be passed toUIApplicationDelegate
. You can handle it there to decide which View to open. - if the app is not installed,
https://yourdomain.com/dress/1
will be opened with Safari and you can still display the product on your website or redirect the user to App Store
Universal links sound like a perfect solution for iOS. But again, unfortunately, they have their limitations.
- Universal links only work with Safari and Chrome
- When another site redirects with a universal link, it works only if the click happens within Safari and Chrome. For instance, if there is a link in your Email app
https://anotherDomain.com/
redirecting to the universal linkhttps://yourDomain.com/dress/1
, it won’t deeplink into your App. But if the linkhttps://anotherDomain.com
is clicked from Safari, it works. - Universal links won’t work if you paste the link directly into address bar.
- Universal links won’t work if the redirect is triggered by JavaScript.
- Universal links won’t work when you open the link programmatically inside your app (with
openUrl
, for instance)
Welcome to the world of deep links
Deep linking is complicated – there is no silver bullet that works in all scenarios. Fortunately, Adjust will detect all those scenarios and use the best strategy to make deep linking functional. You can read more about Adjust deep linking here and ping [email protected] if you have more questions.