Deep Links
A deep link is an external URI that, when clicked, opens a specific scene in your app. After following the configuration instructions, your app is ready to respond to deep link clicks. You create a function inside App.js
that receives the incoming deep link and navigates to the relevant scene. You hook this function up to the Linking
API of React Native (outside of any component). In our email example, when a user clicks a link like 'email://app?id=12' we navigate them to the 'mail' scene for that id. Follow the testing instructions to check that the deep link behaves as expected.
import {Linking} from 'react-native';
const openLink = (url) => {
if (url) {
const id = +url.split('=')[1];
stateNavigator.navigate('mail', {id});
}
};
Linking.getInitialURL().then(openLink);
Linking.addEventListener('url', ({url}) => openLink(url));
Priming the Stack
If the user has the app open in the background when they click a deep link, then the new scene is pushed on top of their current stack. In our email example, we can end up with two 'mail' scenes on top of the stack. The user opens the first 'mail' scene inside the app and the second 'mail' scene is pushed on top when they click the deep link. We can fix this by using the Navigation router's fluent navigation to build the exact stack we want. We want to open the mail from the deep link directly on top of the 'inbox' scene.
const openLink = (url) => {
if (url) {
const id = +url.split('=')[1];
const link = stateNavigator.fluent()
.navigate('inbox')
.navigate('mail', {id}).url;
stateNavigator.navigateLink(link);
}
};
Configuring
Android
Locate the AndroidManifest.xml
in the Android project and add the following, replacing the scheme and host strings to match your URI pattern:
<activity
android:name="com.navigation.reactnative.LinkActivity"
android:launchMode="singleTask"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="email" android:host="app" />
</intent-filter>
</activity>
iOS
Open your iOS project in Xcode, select the project in the sidebar and navigate to the Info tab. Scroll down to the 'URL Types' section and add one that matches your URI pattern. In our email example, we'd enter an Identifier of 'email' and a URL Scheme of 'email'.
Locate the AppDelegate.m
in the iOS project and add:
#import <React/RCTLinkingManager.h>
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
options:(NSDictionary *)options
{
return [RCTLinkingManager application:application openURL:url options:options];
}
Testing
Android
Run the following command, changing the link to match your URI pattern and the namespace to match your project:
adb shell am start -W -a android.intent.action.VIEW -d "email://app?id=12" com.email
iOS
Run the following command, changing the link to match your URI pattern:
xcrun simctl openurl booted "email://app?id=12"