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
A common and old technique to solve this problem is using
1 2 3 4 5 6 7 8
By doing this, the browser will try to load
- If your app is not installed, then nothing will happen while loading
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
Since Chrome for Android version 25 and later, the above code stopped working
according to Chrome documentation.
Fortunately, Google provides the
Intent URL for a better solution. When a user
clicks on the URL
- 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:
|Chrome 24 or below||√|
|Chrome 25 or above||√|
|Facebook in-app Browser||√|
|Twitter in-app Browser||√|
Deep links for iOS
Assuming your deep link URL is
yourapp://path/ and your app ID in app Store
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:
|iOS 8 or below Safari||√|
|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
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
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
One domain can be associated with multiple apps and vice versa.
Next, you need to adopt the
UIApplicationDelegate methods for Handoff
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
"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/1will be passed to
UIApplicationDelegate. You can handle it there to decide which View to open.
- if the app is not installed,
https://yourdomain.com/dress/1will 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 link
https://yourDomain.com/dress/1, it won’t deeplink into your App. But if the link
https://anotherDomain.comis clicked from Safari, it works.
- Universal links won’t work if you paste the link directly into address bar.
- 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 firstname.lastname@example.org if you have more questions.