Implementing Deep Linking in a React Native Application
Vishal Singh
Posted on April 3, 2024
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! 🚀
Posted on April 3, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.