Deep Dive Into Deep Link. Part 1. Introduction and the initial problem
The reason for this material was a task from our past project. The goal was to expand the coverage of the application’s content with new Deep Links. It all sounded simple, but when we started testing the solution, there were some non-obvious problems: on different versions of Android, shells, devices, and applications, Deep Links worked differently.
Do you know the answers to these questions?
- How will the Deep Link work on a link if opened in the SMS client of Honor 9 Lite (Android 9.0, EMUI 9.1.0)?
- What if we try it in Gmail on Samsung A70 (Android 10.0, One UI 2.5)?
- Or try Telegram on Xiaomi Mi5 (Android 8.0, MIUI Global 10.2.2.0)?
We know because we conducted 280+ tests and saw everything with our own eyes! We also learned how to process links at the application level (Linkify, HTML, Span), how their dispatching is performed (Jetpack Navigation Component, airbnb/DeepLinkDispatch, Custom), what nuances of Android we have to deal with and how to soften these blows :)
We hope this series of articles will help you save time and effort when working with Deep Links.
In this part, we will define the main concepts: Deep Link, Web Link, App Link. We will consider the features of each type of Deep Link and the differences between them.
What is deep Link?
Before we start our deep dive, let’s clarify what a Deep Link is.
Deep links are URIs of any scheme that take users to your app
according to developer.android.com. Let’s break down this definition into parts.
Deep links are URIs of any scheme that take users to your app
What are URIs? They are resource identifiers. What types of URIs are there? This is where it gets a bit more complicated. The main difficulty lies in classifying URLs and URNs. You can read more about the “classical” and “modern” view of these concepts here.
We will use the classification from the picture: URI — a general identifier, URL and URN are its subsets that do not intersect.
But that’s not all. Let’s take a look at the table.
There turned out to be many more types, and we are sure that not all of them are represented in the table. Let’s briefly discuss some of them:
- IRI — a URI with support for various languages of the world
- Uniform Resource Characteristics — defines metadata about a resource
- PURL — Persistent URL that does not involve changes (used to avoid 404 errors)
Graphically, this table can be represented as follows:
A few words about the URI format. It consists of mandatory parameters:
- scheme — defines the context / meaning of the identifier
- path — hierarchical data for identifying the resource.
And optional parameters:
- userinfo — information about who interacts with the resource
- host — the location of the resource
- port — the point of interaction with the host / specific process or service
- query — non-hierarchical data for identifying the resource
- fragment — identification of a secondary resource within the original resource.
You can read more about the parameters here and here.
Deep links are URIs of any scheme that take users to your app
The next part of the definition is about schemes. A deep link is a URI of any scheme. There are many schemes. If a scheme is registered with IANA, it is considered official. Some of the popular official schemes are:
- geo:55.79378663446035,49.11699501723111
- mailto:metakratos.com
- tel:+9982776…
- sms:+99832776…?body=hello%20metakratos
- Other examples here
If a scheme is not registered with IANA, it is unofficial. But even so, there are schemes that have gained popularity in the community, for example:
- jdbc:mysql://host:port/database?params…
- slack://open?team={TEAM_ID}
- zoommtg://zoom.us/join?confno=<confno>…
- Other examples here
Mobile deep links are one example of a class of unofficial URI schemes that allow for linking directly to a specific location in a mobile app
There are special subtypes of unofficial schemes that are used for transitioning to mobile apps. Perhaps some of you have seen something like this:
- myapp://example/path/to/resource
- superapp://example/path/to/resource
- wow://example/path/to/resource
Deep links are URIs of any scheme that take users to your app
Finally, in most cases, a deep link is used to redirect a user to your mobile application.
Again, let’s remember developer.android.com. It says something like this:
Users following links on devices have one goal in mind: to get to the content they want to see
Seems simple :)
But it wouldn’t be Android if the story ended like this. Getting to the “content they want to see” takes something else. Have you ever seen this kind of dialog?
When a link is clicked, the system shows the user a disambiguation dialog (not always, but more on that later). It displays a list of candidate apps to handle the link.
The list is generated depending on the reference and intent-filter of the installed applications (more about this afterwards). In addition to the list of applications, two options are available to the user:
- “Just once” opens the selected application and asks you to re-select from the candidate list when you tap again. At the same time, the system may remember the previous selection and show it at the top of the dialog (probably for the user’s convenience).
2. “Always” remembers the selection and will no longer prompt the user to choose. In the app settings, users can find links that are always handled by the app and change the behavior if necessary.
Web Link
Web links are deep links that always use the HTTP, HTTPS schema
Now let’s talk about web link. This is a subspecies of deep link. But unlike them, web links can only have http and https schemas.
Very important point: on Android 11 and below, a click on a web link can be processed by your app, but starting with version 12, web links are only opened in the browser. This may be due to Google’s insistence on using Android App Links.
Android App Link
Android M (23) Will Support App Deep Linking Without That Annoying Selector Prompt
Android 6.0 introduced the ability to perform deep linking without disambiguation dialog. This feature gives the user the option to do no extra steps and make a direct jump to the app, improving the user experience. It is from version 6.0 that Android App Link came into existence.
Android App Links are web links that contain the autoVerify attribute
Let’s go in order.
Q: Why is an app link a web link?
A: Because app link communicates with the web domain via http protocol (link).
https://domain.name/.well-known/assetlinks.jsonQ: Why link to the web domain?
A: In order to perform application verification, i.e. to indicate to the system that this application is responsible for the selected domain (“… to associate an app with a web domain they own.”). It turns out that after successful verification the system knows to whom the link should be addressed and may not open the disambiguation dialog.
https://domain.name/.well-known/assetlinks.jsonQ: How is the binding between the application and the web domain done?
A: Automatically (“…contain the autoVerify attribute”). Let’s look at the diagram. During the installation of the application, the system realizes by the autoVerify attribute in the intent-filter that verification needs to be performed. Since the application is usually downloaded from the network (Google Play Store, for example), this is the most convenient moment to make an http request to a special resource (/.well-known/assetlinks.json, which is described in the Digital Asset Link specification). If successful, the system performs the association. Read more here.
Spoiler for the most inquisitive readers
Get Valery Petrov’s stories in your inbox
Join Medium for free to get updates from this writer.
The inquisitive reader will ask: “What if there’s no internet? Or something goes wrong on the server?”.
Very reasonable questions! They show your professionalism. There are indeed many nuances. Read more here:
1. The domain verification process requires an internet connection and may take some time.
And now we’re moving on.
Earlier we said that web link will not open on Android 12. But web link can be turned into app link and bypass this limitation!
Other Deep Link features
It is also possible to search for content that has a deep link. You can see by example that when typing “Kenny” into the search box, we have the option to go to another app that has a deep link configured to process this information. Read more here and here.
Also deep link are used in addition to instant apps, making the entrance to your app more native and transparent (link). Look at each of the examples: the user clicks on the link and immediately goes to your app (lowering the threshold of entry, expanding funnels, increasing conversions!).
What were we supposed to do?
Now that you’re 50% on the topic, we can move on to breaking down the task. We needed to realize the transition to the application by links:
- scheme: http, https
- host: domain1.domain2.ru, domain1.domain3.ru
- path: /, /landing, /landing/, /path1/path2/{id}
That is to make all these links:
- http://domain1.domain2.ru
- http://domain1.domain2.ru/
- http://domain1.domain2.ru/landing
- http://domain1.domain2.ru/landing/
- http://domain1.domain2.ru/path1/path2/{id}
- http://domain1.domain2.ru/path1/path2/{id}/
- https://domain1.domain2.ru
- https://domain1.domain2.ru/
- https://domain1.domain2.ru/landing
- https://domain1.domain2.ru/landing/
- https://domain1.domain2.ru/path1/path2/{id}
- https://domain1.domain2.ru/path1/path2/{id}/
- http://domain1.domain3.ru
- http://domain1.domain3.ru/
- http://domain1.domain3.ru/landing
- http://domain1.domain3.ru/landing/
- http://domain1.domain3.ru/path1/path2/{id}
- http://domain1.domain3.ru/path1/path2/{id}/
- https://domain1.domain3.ru
- https://domain1.domain3.ru/
- https://domain1.domain3.ru/landing
- https://domain1.domain3.ru/landing/
- https://domain1.domain3.ru/path1/path2/{id}
- https://domain1.domain3.ru/path1/path2/{id}/
have become deeplinks. It’s already hard to look at it… It’s easier just to lose some link or make typos :)
Then we decided to come up with a visual documentation of deep link — Deep Link Tree. It is needed to remember to process no URL and make the view more visual.
Now let’s transfer our task to Deep Link Tree. Initially, our application was not able to handle all possible deep links — they all started with a single https scheme, had one host and ended with several paths.
But this was not enough for us. We wanted to add processing of http links and one more host. At the same time, we wanted to make it all work and not have to write a lot of one-type code.
Now let’s see how it looks like in the code. Inside the intent filter we specify parameters (read more in the documentation):
- First, we specify action VIEW so that our application knows how to handle intent to view content.
- Then be sure to set category DEFAULT to mark the activity as the default event handler.
- Optionally add category BROWSABLE. In this case, we tell the system that our application is able to handle events that occur in the browser.
- The next mandatory tag is data. It describes what data the intent is filtered by. For deep link, this data is the parts of the URL:
- scheme
- host
- port
- different path variants: path, pathPrefix, pathPattern. Their differences will be explained in the following parts
- mimeType
<activity
android:name="com.metakratos.app.MainActivity"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<!-- 1 -->
<action android:name="android.intent.action.VIEW" />
<!-- 2 -->
<category android:name="android.intent.category.DEFAULT" />
<!-- 3 -->
<category android:name="android.intent.category.BROWSABLE" />
<!-- 4 -->
<data android:scheme="http" />
<!-- 5 -->
<data android:host="metakratos" />
<!-- 6 -->
<data android:port="8080" />
<!-- 7 -->
<data android:path="/android/meetup" />
<data android:pathPattern="/*/meetup" />
<data android:pathPrefix="/android" />
<!-- 8 -->
<data android:mimeType="*" />
</intent-filter>
</activity>The original problem has been described. We can start solving it! But before we do, let’s talk about a couple of very important points.
A few more words about Deep Link
Let’s compare URI formats from the main specification and from the Android specification. We’ll mark the common parameters in green and the unique ones in gray. Due to Android limitations, we cannot use the following parameters: userinfo, query, fragment. Therefore, the URI format is truncated to the lower scheme. Note that scheme and host are mandatory (unlike scheme and path in the main specification).
Why this exact format?
There is an assumption that it is to speed up intent-resolution at the point where the system is looking for candidate applications. The fewer attributes, the less to compare, the faster the comparison. This problem will become more pronounced when we talk about regular expressions in path.
It turns out that due to the limitations of the URI format, Android cannot process all their types. From the previously discussed examples, only: URL, PURL, Clean URL can be processed, hence:
Deep links are URIs of any scheme that take users to your app
changes for
Deep links are URLs (but not all) of any scheme that take users to your app
and the classification of identifiers takes the form:
Summary
To summarize. The relationship between deep link, web link, app link can be represented as a pyramid.
At its core, Deep Link is a technology, albeit the oldest, but a basic one. Deep Link is used in notifications, content search, instant apps, data transfer within or between apps, etc. The main objective is to move the user to the mobile app. Web Link aims to attract traffic from web to mobile. Since http links are highly prevalent, it is such links that enable content to spread more widely on the web. Android App Link is a modern and more technically sophisticated Web Link. Aimed at improving user experience and security.
Android imposes restrictions on the URI format. Only four parameters are available for customisation:
- Two mandatory: scheme, host
- Two optional: port, path
To avoid mistakes in your deep links and to make their list more visible, we recommend to pay attention to the Deep Link Tree. To build it, start by defining scheme, then connect them to host, then to path. Deep Link Tree can be represented graphically, a simple list of URLs, XML markup / program code in intent-filter.
Congratulations! You have finished reading the article and can now say to yourself, “I did a great job!” We hope you enjoyed it. Please take the survey and leave a comment (your feedback, impressions, observations, work experience, opinion — anything you find necessary).
See you in part 2!











