---
title: 'Implementing deep linking in React Native: A quick step-by-step guide'
teaser: A quick step-by-step guide on implementing deep linking in a React Native
  application, enabling users to seamlessly access specific screens or content within
  the app.
tags: mobile,react native
author: Diego Oliveira
published_on: 2023-07-21
---

## Introduction

Deep linking is a crucial feature for modern mobile applications. It enables seamless navigation and an improved user experience and allows users to access specific screens or content within an app by clicking on URLs or interacting with external sources like push notifications. In this blog post, we will explore how to implement deeplinking in a React Native application. By the end of it, you will be able to seamlessly integrate deep linking functionality into your app, enabling users to access specific content with just a single tap.

## Prerequisites

To follow along with this tutorial, you should have a basic understanding of React Native. Ensure that you have the React Native environment setup or follow the steps provided in the [official documentation](https://reactnative.dev/docs/environment-setup) for your development OS.

## Reference repository

To check or run the full implementation of this tutorial please reference the example [GitHub Repository](https://github.com/thoughtbot/deeplinkingexample). It contains a barebones React Native application with only the implementation explained in this tutorial.

## Setting up the React Native project

First, let's set up a new React Native project using the React Native CLI. Open your terminal and execute the following command:

```bash
npx react-native init DeeplinkingExample
```

This command will create a new project named "DeeplinkingExample" on your current folder.

## Installing dependencies

To implement this deep linking example we will use the React Navigation library as it is widely used by the community for handling navigation and deep linking in React Native apps.

Navigate to the project folder:

```bash
cd DeeplinkingExample
```

Next, install the required dependencies:

```bash
npm install @react-navigation/native @react-navigation/native-stack react-native-screens react-native-safe-area-context
```

The additional libraries are meant to expose the native navigation components and safe-area to React Native.

Update your iOS Pods:

```bash
npx pod-install
```

## Setting up basic navigation

In your `App.tsx` file add the following code. It includes two example screens (Home and Details), accessible through a standard Stack Navigator. The Home screen displays a list of grocery items that when selected take the user to a Details screen that shows the item:

```tsx
import * as React from "react";
import { Button, View, Text, FlatList, StyleSheet, TouchableOpacity } from "react-native";
import { NavigationContainer } from "@react-navigation/native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";

/**
 * Data
 */
const groceryItems = [
  { id: 1, name: "Apples" },
  { id: 2, name: "Bananas" },
  { id: 3, name: "Oranges" },
  { id: 4, name: "Milk" },
  { id: 5, name: "Bread" },
];

/**
 * Screens
 */
function HomeScreen({ navigation }) {
  return (
    <View style={styles.container}>
      <Text>Grocery List</Text>
      {/* FlatList to render the list of grocery items */}
      <FlatList
        style={styles.list}
        data={groceryItems}
        keyExtractor={(item) => item.id.toString()}
        renderItem={({ item }) => (
          <TouchableOpacity
            style={{ padding: 10, borderBottomWidth: 1 }}
            onPress={() => navigation.navigate("Details", { id: item.id })}
          >
            <Text>{item.name}</Text>
          </TouchableOpacity>
        )}
      />
    </View>
  );
}

function DetailsScreen({ route, navigation }) {
  return (
    <View style={styles.container}>
      <Text>
        Item:
        {groceryItems.find((item) => item.id === Number(route.params.id))
          ?.name ?? "Not Found"}
      </Text>
      <Button title="Back" onPress={() => navigation.goBack()} />
    </View>
  );
}

/**
 * Stack Navigator
 */
const Stack = createNativeStackNavigator();

/**
 * StyleSheet
 */
const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
  list: {
    width: '100%',
  },
  button: {
    padding: 10,
    borderBottomWidth: 1,
  },
});

function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator initialRouteName="Home">
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Details" component={DetailsScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}

export default App;
```

## Integrating deep linking in app entry point

To open the app based on the `myapp://` uri run the following command to add the necessary schemes in the native projects:

```bash
npx uri-scheme add myapp
```

The `myapp` in the uri is an arbitrary and can be changed to any custom name you prefer. The [uri-scheme](https://www.npmjs.com/package/uri-scheme) is a stand-alone package by Expo that simplifies the process of editting and setting up uri schemes within the native code.

## Linking Navigation

Create a linking configuration object to be added to your navigation container.

```tsx
/**
 * Linking Configuration
 */
const linking = {
  // Prefixes accepted by the navigation container, should match the added schemes
  prefixes: ["myapp://"],
  // Route config to map uri paths to screens
  config: {
    // Initial route name to be added to the stack before any further navigation,
    // should match one of the available screens
    initialRouteName: "Home" as const,
    screens: {
      // myapp://home -> HomeScreen
      Home: "home",
      // myapp://details/1 -> DetailsScreen with param id: 1
      Details: "details/:id",
    },
  },
};
```

Then add the linking to your navigation container

```tsx
<NavigationContainer linking={linking}>
  <Stack.Navigator initialRouteName="Home">
    <Stack.Screen name="Home" component={HomeScreen} />
    <Stack.Screen name="Details" component={DetailsScreen} />
  </Stack.Navigator>
</NavigationContainer>
```

## Testing deep linking

To test deep linking in your React Native application, first run:

```bash
npx react-native start
```

This command starts the Metro server. Next, open another terminal tab and execute:

```bash
npx react-native run-android
```

or

```bash
npx react-native run-ios
```

Ensure that the app is installed and running on your iOS Simulator or Android Emulator. To trigger a deep link, you can use the following commands based on the platform you are running:

For iOS:

```bash
xcrun simctl openurl booted "myapp://home"
```

For Android:

```bash
adb shell am start -W -a android.intent.action.VIEW -d "myapp://home"
```

### Testing deep links with params

In our linking configuration we specified a special link capable of taking parameters embedded in the uri and enables you to pass specific navigation params in your deeplink that will be accessible through the screen's `route.param` prop.

```jsx
Details: "details/:id";
```

In this configuration the `id` param can be passed in the app's URI, for instance `myapp://details/1`, and will be accessible in the `DetailsScreen` from the route prop `route.params.id`.

```bash
xcrun simctl openurl booted "myapp://details/1"
```

Congratulations! You have successfully implemented deep linking in your React Native application. Now, your users can access specific screens or content within your app through deep links.

## Conclusion

In this tutorial, we learned how to implement deep linking in a React Native application. We configured deep linking, set up the necessary navigation, and handled the deep link URL to navigate to the appropriate screen. By following these steps, you have a basic setup that can be expanded to cover all cases for your application and enhance the user's experience and engagement by allowing seamless access to specific content within your app. Great work!

## Want to go deeper?

Do you have an app concept that needs to be market-ready and scale? Do you need a modern, mobile-first approach to an already existing platform? [Learn how thoughtbot](https://thoughtbot.com/services/react-native-development) can help grow your product.
