How to Implement Deep Linking in React Native (2025 Guide)

Ever wondered how clicking an Amazon product link sent to you on WhatsApp or email opens the Amazon app directly to that exact product skipping the browser entirely?
That magic is called deep linking.

In this article, we’ll explore how deep linking works and how you can implement it in your React Native app.

How Deep Linking Works

Deep linking allows external URLs, whether from a browser, email, SMS, QR code, or another app to open a specific screen within your app rather than just launching it on the home screen.

For example:

  • myapp://workout/123 might take the user directly to a workout detail page.

  • https://myapp.com/posts/456 might open a blog post inside your app instead of the website.

This is especially useful for:

  • Personalized onboarding flows

  • Sharing content between users

  • Marketing campaigns

  • Push notifications or emails that point to specific features

When a user taps on a link, both Android and iOS have their own way of deciding how to handle it.

On Android, the operating system looks through all installed apps to see if any of them have registered to handle that type of link using what's called an intent filter. If your app is configured to handle a custom URL scheme like myapp://..., or a verified web domain like https://myapp.com, Android will either show your app as an option to open the link or launch it directly especially if you've set up App Links (Android's version of verified web links) for automatic opening. However, if the app isn’t installed, links using custom schemes will do nothing, while App Links will open in the device’s default browser.

On iOS, the system handles incoming links through either custom URL schemes or Universal Links. If your app is installed and Universal Links are properly configured and verified with your domain, iOS will bypass Safari and open your app directly to the matching screen. If not, the link simply opens in Safari, behaving like a normal web link.

Setting Up Deep Linking in a React Native App

Step 1: Create a New React Native Project

npx @react-native-community/cli@latest init DeepLinkingDemo
cd DeepLinkingDemo

Step 2: Install React Navigation and Dependencies

npm install @react-navigation/native
npm install react-native-screens react-native-safe-area-context react-native-gesture-handler react-native-reanimated react-native-vector-icons
npm install @react-navigation/native-stack

Don’t forget to install pods (for iOS):

npx pod-install

Step 3: Setup for iOS

To be able to listen to incoming links add following lines:

(for swift code / AppDelegate.swift)
Add the following methods inside your AppDelegate class:

import UIKit
import React
import React_RCTAppDelegate
import ReactAppDependencyProvider

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
  var window: UIWindow?

  var reactNativeDelegate: ReactNativeDelegate?
  var reactNativeFactory: RCTReactNativeFactory?

  func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
  ) -> Bool {
    ...
    ...
    return true
  }

// Deep linking  custom URL scheme example://
// -----ADD THIS-----
  func application(_ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
  return RCTLinkingManager.application(application, open: url, options: options)
}
}
// --------------------

You can also support universal links, which allow your app to open from standard HTTPS URLs like
https://deeplinkingdemo.com


// Deep linking  custom URL scheme example://
// -----ADD THIS-----
  func application(_ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
  return RCTLinkingManager.application(application, open: url, options: options)
}

// Deep linking for Universal links (https://example.com/...)
// -----ADD THIS-----
  func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
    return RCTLinkingManager.application(application, continue: userActivity, restorationHandler: restorationHandler)
  }
// --------------------

For Universal links, you will have to set up app domain as well from xcode.

  1. launch the app in Xcode and click on signing capabilities tab

  2. Click on “+capability” to add a new capability and add associated domain

  3. Add your domain name

Last step for iOS

At the bottom of Info.plist, add:

<!-- Deeplinking -->
    <key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLSchemes</key>
    <array>
      <string>deeplinkingdemo</string>
    </array>
  </dict>
</array>

Step 4: Setup for android

To make this work on android, you have to add a new intent in AndroidManifest.xml

DeepLinkingDemo/android/app/src/main/AndroidManifest.xml

 <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="deeplinkingdemo" />
    </intent-filter>

Similar to iOS to support universal links add following intent to the same AndroidManifest file

 <intent-filter android:autoVerify="true">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="http" />
        <data android:scheme="https" />
        <data android:host="www.deeplinkingdemo.com" />
    </intent-filter>

Step 5: basic navigation setup

import { createNativeStackNavigator } from "@react-navigation/native-stack";
import { NavigationContainer } from "@react-navigation/native";
import HomeScreen from "./src/screens/HomeScreen";
import ProductDetails from "./src/screens/ProductDetails";

const Stack = createNativeStackNavigator()

function App() {

  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="ProductDetails" component={ProductDetails} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default App;

Step 6: Setting up a linking config

To enable deep linking in your React Native app, you need to configure your NavigationContainer with a linking config.
The configuration object consists of -
1. prefixes array - An array of URI schemes or domains your app should handle.
2. config object - Contains a screens object that define how incoming URLs map to specific screens in the app. In this screens object, the keys corresponds to a screen name used in your navigation setup, while the value defines the URL path pattern that will trigger navigation to that screen.

import { createNativeStackNavigator } from "@react-navigation/native-stack";
import { NavigationContainer } from "@react-navigation/native";
import HomeScreen from "./src/screens/HomeScreen";
import ProductDetails from "./src/screens/ProductDetails";

const Stack = createNativeStackNavigator()

function App() {

  const linkingConfig = {
    prefixes: [
      'https://deeplinkingdemo.app',
      'deeplinkingdemo://',
    ],
    config: {
      screens: {
        Home: 'home',
        Profile: 'profile/:userId',
      }
    }
  }

  return (
    <NavigationContainer linking={linkingConfig} >
      <Stack.Navigator>
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="ProductDetails" component={ProductDetails} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default App;

Remember that Amazon product link example from the beginning? Deep links not only open a specific screen in your app they can also carry data, like product IDs or user profiles, to display relevant content right away.

In React Navigation, this is done by defining dynamic segments in the linking configuration. You use a colon (:) to indicate a dynamic part of the URL (like :id), which is then passed as a route parameter to your screen.

Linking config:

 linking = {
  prefixes: [
      'https://deeplinkingdemo.app',
      'deeplinkingdemo://',
    ],
  config: {
    screens: {
      ProductDetails: 'product/:id',
    },
  },
};

ProductDetails screen:

import { StyleSheet, Text, View } from 'react-native';
import React from 'react';
import { useRoute } from '@react-navigation/native';

const ProductDetails = () => {
  const route = useRoute();
  const { id } = route.params;

  return (
    <View>
      <Text>Product for: {id || 0}</Text>
    </View>
  );
};

export default ProductDetails;

So if you open a link like deeplinkingdemo://product/123, it’ll land you on the ProductDetails screen with 123 passed as the id parameter just like those deep links that open right to an Amazon product.

open Safari or chrome in your simulator / device and paste the link

deeplinkingdemo://home

You can also try simulating opening a deep link using command for your simulator (for iOS)

  xcrun simctl openurl booted "deeplinkingdemo://home"

for Android emulator

adb shell am start -W -a android.intent.action.VIEW -d "deeplinkingdemo://home" com.deeplinkingdemo

And we are done 🎉

Conclusion

You can find the complete source code for this setup here 👇
https://github.com/abhishek-sonawane/deepLinkingDemo

Thanks for reading! If you found this article helpful, share it with fellow developers and let me know your thoughts or questions in the comments. Happy coding! 🚀

4
Subscribe to my newsletter

Read articles from Abhishek Sonawane directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Abhishek Sonawane
Abhishek Sonawane

Mobile & Full-Stack Developer based in Mumbai, India. I love building sleek mobile and web apps, and I share what I learn along the way here. Outside of tech, I enjoy fitness, reading, and exploring new ideas.