All businesses aim to make their apps used by customers as often as possible. Make users return back to the application is always a challenge, and today we’ll check one of the main approaches for it — deeplinks. Our team learned some lessons when implementing deeplinks logic in apps with 10M+ downloads. I’m happy to share our findings below.

Building blocks

Take a look at the following URL:

https://www.example.com/demo?userid=100&client=android

It’s just another URL, it can be counted as a deeplink, and contains the following elements:

https is a scheme

is a scheme www.example.com is a host

is a host /demo is a path, identifying the specific resource

is a path, identifying the specific resource ?userid=100&client=android is a query string with key-value pairs

Deeplink types

Let’s add some definitions to understand available deeplink types.

Deeplink is a link that navigates to a piece of content. This is the most generic type of the link [1]. In the most generic case user will see the app registered for a deeplink in the “open with” dialog.

is a link that navigates to a piece of content. This is the most generic type of the link [1]. In the most generic case user will see the app registered for a deeplink in the “open with” dialog. Deeplink may use a custom URI scheme, for example myapp:// .

. Deeplink may use URI schemes that point to a resource over the network [2]. For example, https:// . In that case we can say that it is a URL .

. In that case we can say that it is a . Android App Link (API 23+) is a HTTP URL Deeplink that can bring users directly to the app content. Corresponding website setup is required if you’d like to verify the ownership for the link [3].

One more type of deeplink we need to mention is a Deferred Deep Link. It allows to handle specific parameters (eg, a product id) in case if app is not yet installed, and user was sent to Play Store. After the app installation the user will be navigated to the expected page. This type of logic is provided by external tools and is out of scope for this article.

Use-case

All types of deeplinks defined above may be used to show the application in the “open with” dialog. It will appear together with a browser and/or other apps registered for the provided URI scheme.

In case if the Android App Link is configured the chooser dialog won’t be shown when the app is installed. The user will be navigated to the app immediately. Please note that this feature is only available since Android 6.0 (API 23).

How to catch a deeplink

To catch a specific deeplink you need to do the following:

Setup a proper <intent-filter> in your Manifest as an entry point.

in your Manifest as an entry point. Consider setting android:launchMode="singleTask" for the target Activity to avoid running multiple copies of your Activity on the same time.

for the target Activity to avoid running multiple copies of your Activity on the same time. Handle the Intent .

. Match the deeplink with predefined regular expressions to navigate the user to the proper page/content.

All this is well-documented and described in several blog posts. See, for example, [3] and [4]. You can also use the App Links Assistant [5] in Android Studio to setup IntentFilters without any code and to configure Android App Links. Another library-based approach for deeplink handling was designed by AirBnb team in the DeepLinkDispatch library [6].

Something we learned the hard way

You can’t use a fair regex in the Manifest intent filter. Documentation says that intent-filter’s android:pathPattern attribute may contain only specific wildcards: An asterisk ( * ), period followed by an asterisk ( .* ), and also an escape character // . This means you need to be creative in setting up patterns [7], and won’t be able to set an “exclude” condition in the pattern.

Some apps may decide to block external navigation, and thus block opening your app via deeplink. For example, some of messenger and browser apps [1] may not allow to open an external app with HTTP deeplink. They will force the content to be shown inside their in-app browser.

Handle all possible deeplinks. Design-wise you should be always able to navigate user to the proper page inside the app if the app is “subscribed” for this deeplink. Since you are not able to use a fair pattern matching on the Manifest side, you must setup a page which will catch all unmatched links. In this case it may make sense to land user to the homepage, or another related content.

Validation and security. It’s a good practice to treat a deeplink as just another user input in your app. It means that you should validate the deeplink and it’s parameters. Moreover, deeplink could navigate the user to the secure or hidden part of the application, so these scenarios definitely worth checking in your test plan.

Separate Activity. One thing you should definitely consider is making the deeplink entry point isolated from the main entry point of the app. This may have several benefits, including logic separation in the code, testability and convenience of tracking implementation.

Deeplink tracking. Tracking requirements is something you should expect in your app design starting from the day one. In the deeplink case the most common requirement is to attach some specific parameters to the link. The example of such link with parameters is the following:

https://e.co/news?utm_source=news&utm_medium=email&utm_campaign=cmp1

How to test your deeplinks

You may check the correctness of test links matching your Manifest setup via the tool provided in Android Studio for configuring App Links [4].

End-to-end way of testing deeplinks is about sending the link via the adb command to the connected test device and checking the device/app behavior. For example, for deeplink your-uri you should execute the following:

adb shell am start -a android.intent.action.VIEW -d "{your-uri}"

From the user and product manager perspective adb probably won’t be the most convenient way :) For this case we can do the following:

Install a barcode scanner app, for example, ZXing Generate a barcode of your target deeplink using a QR-code generator website, for example, qr-code-generator. Scan this barcode with a scanner app. Make sure you see your app in the list of options in the chooser, and select this option.

That’s all Folks

Thanks for reading this post! I’d be happy to hear your feedback, and your stories about dealing with deeplinks. Follow ProAndroidDev publication for more great Android posts :)

Further reading

[1] Universal Links, URI Schemes, App Links, and Deep Links: What’s the Difference?

[2] Uniform Resource Identifier

[3] Android Developers: Handling Android App Links

[4] Deep Linking in Android by Tanner Perrien

[5] Android Developers: Add Android App Links

[6] DeepLinkDispatch library on GitHub

[7] Discussion: Matching a URL pattern