DEV Community

Cover image for Implementing Deep Linking in a React Native Application
Vishal Singh
Vishal Singh

Posted on

Implementing Deep Linking in a React Native Application

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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

yarn add @react-navigation/stack
Enter fullscreen mode Exit fullscreen mode

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>
  );
}
Enter fullscreen mode Exit fullscreen mode

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>
  );
}
Enter fullscreen mode Exit fullscreen mode

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>
  );
}
Enter fullscreen mode Exit fullscreen mode

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>
  );
}
Enter fullscreen mode Exit fullscreen mode

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>
  );
}
Enter fullscreen mode Exit fullscreen mode

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! 🚀

Top comments (0)