Implementing Deep Linking in a React Native Application
Tags: reactnative, javascript, mobile, developer
Published: 2024-04-03 05:48:14

Deep linking is a way of allowing users to navigate directly to specific screens or content within an application. In this article, we’ll explore how to implement deep linking in a React Native application using the React Navigation library.



### Prerequisites

Before we get started, make sure you have the following installed on your machine:

- Node.js and NPM or Yarn

- React Native CLI

- A code editor of your choice

### Getting Started

Let’s start by creating a new React Native project:

```
npx react-native init DeepLinkProject
```


Next, install the required dependencies for React Navigation:


```
yarn add @react-navigation/native
yarn add react-native-reanimated react-native-gesture-handler react-native-screens react-native-safe-area-context @react-native-community/masked-view
```


We also need to install `react-navigation/stack` which is the package we'll be using for navigation:

```
yarn add @react-navigation/stack
```


### Setting up Deep Linking with React Navigation 

To implement deep linking, we’ll use the `Linking` API provided by React Native. We'll also use the `useEffect` hook to handle deep links.


Let’s start by setting up the Stack Navigator in our `App.tsx` file:


```
import * as React from 'react';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { Text, View } from 'react-native';

const Stack = createStackNavigator();

function HomeScreen() {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Home Screen</Text>
    </View>
  );
}

function ProfileScreen() {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Profile Screen</Text>
    </View>
  );
}

export default function App() {
  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen name="Profile" component={ProfileScreen} />
      </Stack.Navigator>
    </NavigationContainer>
  );
}
```

We’ve created two screens: `HomeScreen` and `ProfileScreen`. Now, let's add deep linking to these screens.


We’ll first create a `useEffect` hook in the `App` component to handle deep links. Here, we'll add an event listener to `Linking` that will parse the incoming URL and navigate to the corresponding screen:


```
import * as React from 'react';
import { Linking } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { Text, View } from 'react-native';

const Stack = createStackNavigator();

function HomeScreen() {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Home Screen</Text>
    </View>
  );
}

function ProfileScreen() {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Profile Screen</Text>
    </View>
  );
}

export default function App() {
  React.useEffect(() => {
    const handleDeepLink = ({ url }: { url: string }) => {
      const route = url.replace(/.*?:\/\//g, '');
      const routeName = route.split('/')[0];

      if (routeName === 'profile') {
        const username = route.split('/')[1];
        navigation.navigate('Profile', { username });
      }
    };

    Linking.addEventListener('url', handleDeepLink);

    return () => {
      Linking.removeEventListener('url', handleDeepLink);
    };
  }, []);

  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen
          name="Profile"
          component={ProfileScreen}
          options={({ route }) => ({ title: route.params.username })}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
}
```


In the `useEffect` hook, we first define a function `handleDeepLink` that will handle the incoming deep link. We extract the route name and any parameters from the URL, and navigate to the corresponding screen using `navigation.navigate`.


In the `ProfileScreen`, we can then access the `username` parameter using `route.params.username`, and set it as the screen's title using the `options` prop.


### Folder Structure


`MyProject/
├─ __tests__/
├─ android/
├─ ios/
├─ src/
│  ├─ screens/
│  │  ├─ HomeScreen.tsx
│  │  ├─ ProfileScreen.tsx
│  ├─ App.tsx
├─ package.json`


We’ll keep our React Navigation stack in the `App.tsx` file, and create separate files for each screen in the `screens` folder.


### Full Code

Here is the full code for the application:

### App.tsx




```
import * as React from 'react';
import { Linking } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { Text, View } from 'react-native';

import HomeScreen from './screens/HomeScreen';
import ProfileScreen from './screens/ProfileScreen';

const Stack = createStackNavigator();

export default function App() {
  React.useEffect(() => {
    const handleDeepLink = ({ url }: { url: string }) => {
      const route = url.replace(/.*?:\/\//g, '');
      const routeName = route.split('/')[0];

      if (routeName === 'profile') {
        const username = route.split('/')[1];
        navigation.navigate('Profile', { username });
      }
    };

    Linking.addEventListener('url', handleDeepLink);

    return () => {
      Linking.removeEventListener('url', handleDeepLink);
    };
  }, []);

  return (
    <NavigationContainer>
      <Stack.Navigator>
        <Stack.Screen name="Home" component={HomeScreen} />
        <Stack.Screen
          name="Profile"
          component={ProfileScreen}
          options={({ route }) => ({ title: route.params.username })}
        />
      </Stack.Navigator>
    </NavigationContainer>
  );
}
```


### screens/HomeScreen.tsx




```
import * as React from 'react';
import { View, Text, Button } from 'react-native';

interface Props {
  navigation: any;
}

export default function HomeScreen({ navigation }: Props) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Home Screen</Text>
      <Button
        title="Go to Profile"
        onPress={() => navigation.navigate('Profile', { username: 'johndoe' })}
      />
    </View>
  );
}
```


### screens/ProfileScreen.tsx



```
import * as React from 'react';
import { View, Text } from 'react-native';

interface Props {
  route: any;
}

export default function ProfileScreen({ route }: Props) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Text>Profile Screen</Text>
      <Text>{route.params.username}</Text>
    </View>
  );
}
```


### Conclusion

In this article, we’ve explored how to implement deep linking in a React Native application using the React Navigation library. We’ve also covered considerations for different platforms and versions and provided code samples in TypeScript.

If you like the article, please give it a like, Thanks 🙏🏽
Happy Coding! 🚀