This article complements the Webinar on Deep Linking that can be found here (in Polish). If you want to know more, check out the video!
Imagine that you have an app that clones Medium’s functionality and allows users to add and read articles. Now, users probably want to share or promote a good content, but how can you help them navigate directly to a specific article? This is where Deep Links comes into play!
So now we know that Deep Link is a simple URI that directs a user to desired content rather than just launching the home page/main screen.
The most basic form (and easiest to implement) of a Deep Link in mobile apps is a custom URI scheme. For example, you can define a scheme like vd:// for your app that launches the app, but something like vd://careers/react-native will take a user to the screen with React Native career description.
Your app can have any scheme and it’s not unique (like bundle ID) or verified. This means that you can have two apps installed on your phone that use the same scheme. This is also a vulnerable part of custom schemes, because it allows malware apps to try to intercept information transmitted to your application via a Deep Link. Another disadvantage is that custom schemes do not handle any fallbacks in cases where your app is not installed. It simply will not work.
This is why another approach came up (and currently is strongly recommended by Apple) which is using a traditional http:// link that opens a web browser. First of all, it is safer because it requires that you own the domain to which links are redirecting. It also handles the process if the user does not have your app installed — it just opens the website in the browser.
On iOS, these links are called Universal Links, and on Android, App Links.
Now, let’s dive straight into implementation. You can use this tutorial to implement Deep Links in your already existent app or you can run ‘npx react-native init TestDeepLinking’ to follow.
Official docs: https://developer.apple.com/library/archive
/documentation/General/Concept
ual/AppSearch/UniversalLinks.html
If you’ll try to run your custom scheme in Safari on your device or in simulator, you’ll see something like this:
To support a custom scheme, let’s say vd:// we need to perform 2 steps.
To do this, go to your Target Info and add a new URL Type. As an ‘Identifier’ you can use your bundle ID, for ‘URL Scheme’ you can use whatever you want. We will use vd. As ‘Role’ in this case leave ‘Editor’, but if you’re going to invoke other app’s schemes from within your app (eg. mailto://), then you would change it to ‘Viewer’.
Go to AppDelegate.m and add this openURL method that handles incoming URLs using RCTLinkingManager provided by React Native. Please note that official docs will stress that you need to link this library, but in this version of React Native this is no longer needed and you are good to go.
Build your app. When you make native changes you have to rebuild it to see the effect of your work. Regular refresh won’t be enough.
Now, test if the custom scheme is working properly. Go to Safari on your device or in simulator and type in ‘vd://’. This should detect that the app is installed and ask you if you want to open the app.
Please note, for this you’ll need a Developer Account that is fully approved by Apple. Otherwise, you won’t be able to set Associated Domains Capability in XCode.
First, you need to enable “Associated Domains’ in your project settings. To do so, go to your Target’s ‘Signing and Capabilities’ and add a new capability. Use ‘applinks:’ prefix for your domain to tell XCode that this domain is used for Universal Links.
Last but not least, you have to make sure that AASA (Apple App Site Association) file is properly uploaded to your server and available under this link (https is important):
https://your-domain.com/Here, the appID is your app’s bundle ID prefixed with your team’s ID. If you log in you can find it on developer.apple.com under Membership. The second property after appID is an array of supported paths. Also, it is possible to add more than one app —for example, if you have multiple bundleIDs per environment. Just add another object to the ‘details’ array.
With this all set up, you should have your Deep Link working as expected.
To implement Deep Linking in an Android app, you are going to define Intents that are responsible for starting Activities (launching screens). Intent filter is an expression that specifies the type of intents that components can receive and actions that they perform. We want to show the user a specific screen and for this you’ll need to use the ACTION_VIEW intent action.
Go to android/app/src/main/AndroidManifest.xml and add a new intent filter right below the last one in the <activity> tag.
The android:autoVerify="true" will cause a verification of hosts defined in intent filters. It means that Android will check if your website hosts the Digital Asset Links file.
You can define more domains and more intent filters. Just read official docs carefully, which were super helpful for me.
Again, just like for iOS, make sure that the assetlinks.json file is properly uploaded to your server and available under this link:
https://your-domain.com/.well-known/assetlinks.json.The file in its most basic form should look like this:
The SHA256 fingerprints makes up your app’s signing certificate and is stored in your keystore that you use to sign your app.
To test your app via terminal, type in this command:
$ adb shell am start
-W -a android.intent.action.VIEW
-d "yourscheme://" com.example.android
You can also test Deep Links in Android Studio.
Go to Run -> Edit Configurations. Set the launch options to your scheme, for example vd://careers (assuming that you handle incoming links in React Native and navigate to proper screen).
Handle Links in React Native
Official docs
https://reactnative.dev/docs/linkingAfter you implement everything on the native side, you can handle incoming links. There are two cases.
In this case you’ll use Linking.addEventListener(type, handler) where ‘type’ is the type of triggered event, so pass ‘url’ here, and ‘handler’ is a callback to which clicked link is passed and where you can handle it. For example:
Please remember to cancel any listeners you initialize on unmounting, to do this use removeEventListener(type, handler).
Link opens it and is passed as `initialURL`, so you are going to use Linking.getInitialURL(url).
As you can see I used ‘yourCustomMethodToHandleUrl(url)’ method, this is where you want to:
If you are going to implement a custom scheme, Universal Links and App Links all together, there are a lot of steps to do, so it's not hard to make a mistake. Here is a list of things that might go wrong.
One of the most common mistakes.
For AASA file make sure:
Another common mistake. After you make any changes in native files, rebuild your project.
There is a hidden truth about Deep Links, it’s not going to work the same in all cases, this mostly applies to iOS.
If none of the above helped, take a break. Go for a walk. Come back and check all steps one by one, again...
You should now be able to implement:
That’s a lot. I hope you find this article useful. If you do, please don’t forget to share with other developers.