Deep Linking in React Native with Universal Links and URL Schemes

How to implement deep linking technologies for iOS React Native apps

A Brief History of Deep Linking in iOS

Deep linking was bought to iOS very early on

# URL Schemes can simply navigate to a particular screen
myapp://settings
# or a "deeper" state of the app
myapp://blog/latest/page/5

Universal Links use a website URL scheme to deep link an app

An Open App prompt will appear with web pages configured with Universal Links.

Setting up a URL Scheme

A URL Type defined in Xcode.
#import <React/RCTLinkingManager.h>// ...#pragma mark - Handling URLs- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
return [RCTLinkingManager
application:application openURL:url
sourceApplication:sourceApplication
annotation:annotation
];
}
// ...

Expo projects in development use the exp:// URL Scheme

Changing an Expo project’s URL Scheme

# testing a URL with your URL scheme<url_scheme>://testing

Monitoring URL Events in React Native

yarn add react-native-deep-linking
// constants.jsexport const URL_SCHEMES = [
'exp://',
'myapp://',
];
...
import { URL_SCHEMES } from './constants'
import DeepLinking from 'react-native-deep-linking'
export const App = (props) => { // add URL schemes to `DeepLinking`
for (let scheme of URL_SCHEMES) {
DeepLinking.addScheme(scheme);
}
// configure a route, in this case, a simple Settings route
DeepLinking.addRoute('/settings', (response) => {
navigation.navigate("Settings");
});
// manage Linking event listener with useEffect
useEffect(() => {
Linking.addEventListener('url', handleOpenURL);
return (() => {
Linking.removeEventListener('url', handleOpenURL);
})
}, []);
// evaluate every incoming URL
const handleOpenURL = (event) => {
DeepLinking.evaluateUrl(event.url);
}
return(
<Text>App</Text>
);
}

Setting up Universal Links

Universal Links App Delegate method

// Universal Links- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity
restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
return [RCTLinkingManager
application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler
];
}

Adding Associated Domains Entitlement

Supporting Universal Links with the Associated Domains entitlement and applinks: domain prefix
Associated Domains enabled within App Provisioning

Adding the AASA (Apple App Site Association) File

{
"applinks": {
"apps": [],
"details": [{
"appID": "<TeamID>.com.example.myapp",
"paths": ["/settings", "product/*]
}
]
}
}
https://your-domain.com/.well-known/apple-app-site-association

React to App Launches from Universal Links

// checking if an initialURL is presentconst [initialised, setInitialised] = useState(false);useEffect(() => {
AppState.addEventListener('change', handleAppStateChange);
if (Linking.getInitialURL() !== null) {
AppState.removeEventListener('change', handleAppStateChange);
}
}, []);
const handleAppStateChange = async (event) => {
const initial = await Linking.getInitialURL();

if (initial !== null && !initialised) {
setInitialised(true);
// app was opened by a Universal Link
// custom setup dependant on URL...
}
}

Another Expo URL Gotcha: exps://

const handleAppStateChange = async (event) => {
const initial = await Linking.getInitialURL();
console.log(initial);
}

Troubleshooting Universal Links

App Search API Validation Tool

Sysdiagnose

Other issues

Summary

Programmer and Author. Director @ JKRBInvestments.com. Creator of LearnChineseGrammar.com for iOS and Android.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store