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
# or a "deeper" state of the app

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
// ...

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 = [
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) {
// configure a route, in this case, a simple Settings route
DeepLinking.addRoute('/settings', (response) => {
// manage Linking event listener with useEffect
useEffect(() => {
Linking.addEventListener('url', handleOpenURL);
return (() => {
Linking.removeEventListener('url', handleOpenURL);
}, []);
// evaluate every incoming URL
const handleOpenURL = (event) => {

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

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/*]

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) {
// 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();

Troubleshooting Universal Links

App Search API Validation Tool


Other issues


Programmer and Author. Director @ Creator of 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