Saturday, March 11, 2023
HomeReactHow you can deal with Deep Linking in a React Native app...

How you can deal with Deep Linking in a React Native app by Aman Mittal


How you can deal with Deep Linking in a React Native app

Printed on Mar 29, 2022

•

13 min learn

•

cover

Deep Linking is a method through which a given URL or useful resource is used to open a selected web page or display on cellular. So, as a substitute of simply launching the app on cellular, a deep hyperlink can lead a person to a selected display inside the app, offering a greater person expertise. This specific display could reside below a sequence of hierarchical pages, therefore the time period “deep” in deep linking.

It’s helpful for advertising and marketing campaigns, app-user retention, and so forth. As an software person, you most likely have skilled deep linking when opening a hyperlink, for instance, for a product in an ecommerce retailer from the net browser. When you’ve got the app of that store put in, it might use a deep hyperlink to open the app navigate you on to that product’s display.

On this tutorial, let’s discover ways to deal with deep linking in a React Native app by creating an instance app. We’ll create a easy app that may deal with deep linking and undergo configuring deep linking utilizing React Navigation library.

Supply code of the instance app is accessible at this GitHub Repo.

Configuring navigation in a React Native app

🔗

Let’s begin by creating a brand new React Native software. First, open up a terminal and run the next command:

npx react-native init rnDeepLinking

cd rnDeepLinking

The instance app you’ll construct on this tutorial will comprise two screens. The primary display would be the Residence display with a listing of things. The second display would be the Particulars display which exhibits an merchandise’s particulars.

Let’s configure React Navigation model 6 and set up the required dependencies. It will enable configuring deep linking through navigation and navigating between two screens.

yarn add @react-navigation/native @react-navigation/native-stack react-native-screens react-native-safe-area-context

The following step is to hyperlink all of the libraries you simply put in. This instance app makes use of the 0.67.x React Native model.

On iOS units, you must run the next set of instructions.

For Android, open the file android/app/src/important/java/<Your React Native Mission Title>/MainActivity.java and add the next code snippet:

1bundle com.rndeeplinking;

2

3import android.os.Bundle;

4import com.fb.react.ReactActivity;

5

6public class MainActivity extends ReactActivity {

7

8 /**

9 * Returns the identify of the principle part registered from JavaScript. That is used to schedule

10 * rendering of the part.

11 */

12 @Override

13 protected String getMainComponentName() {

14 return "rnDeepLinking";

15 }

16 @Override

17 protected void onCreate(Bundle savedInstanceState) {

18 tremendous.onCreate(null);

19 }

20}

That is all it is advisable configure React Navigation library in a naked React Native app.

Be aware: The method to configure React Navigation library in a naked React Native mission could change sooner or later. It’s endorsed to observe directions from their official documentation.

Creating Residence and Particulars screens

🔗

Create a brand new listing known as src/screens. It will comprise all of the display parts of the app. Inside it, create two new recordsdata: HomeScreen.js and DetailsScreen.js.

The HomeScreen.js file shows a listing of individuals from an array of mock knowledge from a Json placeholder API. The listing is rendered utilizing a FlatList part from React Native.

Every listing particular person is wrapped by the Pressable part in order that when an app person presses a person’s identify from the listing, they are going to navigate to the Particulars display.

1

2

3import React, { useState, useEffect } from 'react';

4import {

5 ActivityIndicator,

6 View,

7 Textual content,

8 FlatList,

9 Pressable

10} from 'react-native';

11

12import Separator from '../parts/Separator';

13

14const HomeScreen = ({ navigation }) => {

15 const [data, setData] = useState([]);

16 const [isLoading, setIsLoading] = useState(true);

17

18 useEffect(() => {

19 fetch('https://jsonplaceholder.typicode.com/customers')

20 .then(res => res.json())

21 .then(res => {

22 setData(res);

23 setIsLoading(false);

24 })

25 .catch(error => {

26 console.log(error);

27 });

28 }, []);

29

30 const renderList = ({ merchandise }) => {

31 return (

32 <Pressable

33 onPress={() => alert('Navigate to Particulars display')}

34 fashion={{ paddingHorizontal: 10 }}

35 >

36 <Textual content fashion={{ fontSize: 24, coloration: '#000' }}>{merchandise.identify}</Textual content>

37 </Pressable>

38 );

39 };

40

41 return (

42 <View fashion={{ flex: 1 }}>

43 {isLoading ? (

44 <ActivityIndicator coloration="blue" measurement="massive" />

45 ) : (

46 <>

47 <FlatList

48 knowledge={knowledge}

49 contentContainerStyle={{

50 paddingVertical: 20

51 }}

52 keyExtractor={merchandise => merchandise.id}

53 ItemSeparatorComponent={Separator}

54 renderItem={renderList}

55 />

56 </>

57 )}

58 </View>

59 );

60};

61

62export default HomeScreen;

Let’s additionally create a brand new file contained in the src/parts listing and name it Separator.js. This file incorporates a <Separator /> part is used to divide a listing merchandise within the HomeScreen. The <Separator /> part is an easy View with some extra types.

It’s used as a price for the prop ItemSeparatorComponent within the FlatList part. The ItemSeparatorComponent prop defines a customized separator and is rendered between every merchandise within the listing.

1

2

3import React from 'react';

4import { View } from 'react-native';

5

6const Separator = () => (

7 <View

8 fashion={{

9 borderBottomColor: '#d3d3d3',

10 borderBottomWidth: 1,

11 marginTop: 10,

12 marginBottom: 10

13 }}

14 />

15);

16

17export default Separator;

For the main points display, for now, allow us to simply show a textual content string within the display part file DetailsScreen.js:

1import React from 'react';

2import { View, Textual content } from 'react-native';

3

4const DetailsScreen = ({ navigation }) => {

5 return (

6 <View fashion={{ flex: 1, justifyContent: 'heart', alignItems: 'heart' }}>

7 <Textual content>Particulars Display screen</Textual content>

8 </View>

9 );

10};

11

12export default DetailsScreen;

Organising Stack Navigator

🔗

To arrange a Stack Navigator within the app, create a brand new file known as src/navigation/RootNavigator.js and add the next code snippet:

1

2

3import * as React from 'react';

4import { NavigationContainer } from '@react-navigation/native';

5import { createNativeStackNavigator } from '@react-navigation/native-stack';

6

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

8import DetailsScreen from '../screens/DetailsScreen';

9

10const RootStack = createNativeStackNavigator();

11

12const RootNavigator = () => {

13 return (

14 <NavigationContainer>

15 <RootStack.Navigator>

16 <RootStack.Display screen identify="Residence" part={HomeScreen} />

17 <RootStack.Display screen identify="Particulars" part={DetailsScreen} />

18 </RootStack.Navigator>

19 </NavigationContainer>

20 );

21};

22

23export default RootNavigator;

Then, import RootNavigator within the App.js file:

1

2

3import React from 'react';

4

5import RootNavigator from './src/navigation/RootNavigator';

6

7const App = () => {

8 return <RootNavigator />;

9};

10

11export default App;

To construct and run the app, open two situations of the terminal window. Within the first occasion, run npx react-native begin. It will begin the React Native packager.

To construct the app for iOS or Android, run the suitable command from the second occasion of the terminal window. It will construct the app for the platform you specify.

npx react-native run-ios

npx react-native run-android

As soon as the app is constructed, the above command will set up it on the required platform. Right here is an instance of the app working on an iOS simulator and an actual Android system:

js1

Configuring Deep Linking in React Navigation

🔗

There are two methods to deal with Deep Linking in a React Native app:

  • With out navigation: by invoking React Native’s core library through JavaScript and instantly calling Linking. You possibly can study extra about this in React Native’s official documentation
  • With navigation: by configuring React Navigation library

Most production-grade functions have a number of screens and nested navigators. So let’s examine easy methods to implement it with React Navigation in our instance app.

To permit React Navigation library to deal with deep hyperlinks by way of its routing logic, it is advisable outline a configuration object. On this object, outline a prefixes property that incorporates a URI scheme. The app is open primarily based on this URI scheme.

This configuration object is then handed to a prop known as linking on the NavigationContainer. Additionally, add a fallback prop on the container. It’s going to render and show a loading indicator till the deep hyperlink is resolved.

1

2

3

4import { ActivityIndicator } from 'react-native';

5

6const linking = {

7 prefixes: ['peoplesapp://']

8};

9

10const RootNavigator = () => {

11 return (

12 <NavigationContainer

13 linking={linking}

14 fallback={<ActivityIndicator coloration="blue" measurement="massive" />}

15 >

16 <RootStack.Navigator>

17 <RootStack.Display screen identify="Residence" part={HomeScreen} />

18 <RootStack.Display screen identify="Particulars" part={DetailsScreen} />

19 </RootStack.Navigator>

20 </NavigationContainer>

21 );

22};

Utilizing uri-scheme bundle to configure URI schemes

🔗

As a substitute of manually establishing URI schemes for iOS and Android, you need to use the uri-scheme npm bundle. It permits configuring and testing native URI schemes on iOS and Android units. Because of the Expo workforce for creating this bundle and making it accessible to make our developer life simpler.

Be aware: If you wish to dive deep and arrange URI schemes manually for each iOS and Android, take a look at the following two sections.

To arrange the scheme, run the next command for the suitable platform:

npx uri-scheme add peoplesapp --ios

npx uri-scheme add peoplesapp --android

After this step, make certain to construct the app once more for the precise platform utilizing both npx react-native run-ios or npx react-native run-android.

Configuring scheme for iOS

🔗

To manually arrange the scheme for iOS units, open the ios/your-project-name/AppDelegate.m file and add the next code snippet:

1

2#import <React/RCTLinkingManager.h>

3

4

5- (BOOL)software:(UIApplication *)software

6 openURL:(NSURL *)url

7 choices:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)choices

8{

9 return [RCTLinkingManager application:application openURL:url options:options];

10}

Now, let’s add the URI scheme to the iOS mission configuration. Open, Your-app-name/ios/app-name.xcworkspace in Xcode.

Then, choose the mission identify within the left sidebar and navigate to the Data tab:

js2

Subsequent, go to the URL Varieties, click on the + (plus) button, and below the Identifier and URL schemes, add peoplesapp.

js3

The URL Varieties are much like what http represents in an online URL. It’s what’s utilized by iOS to open the app.

After this configuration step, rebuild your iOS app utilizing npx react-native run-ios.

Configuring scheme for Android

🔗

To manually arrange a scheme for Android units, you must configure the scheme. Open /android/app/src/important/AndroidManifest.xml and set the worth of launchMode to singleTask. So as to add the scheme, add a brand new intent-filter tag as proven under:

1

2<exercise

3 android:identify=".MainActivity"

4 android:label="@string/app_name"

5 android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"

6 android:launchMode="singleTask"

7 android:windowSoftInputMode="adjustResize">

8 <intent-filter>

9 <motion android:identify="android.intent.motion.MAIN" />

10 <class android:identify="android.intent.class.LAUNCHER" />

11 </intent-filter>

12

13

14 <intent-filter>

15 <motion android:identify="android.intent.motion.VIEW" />

16 <class android:identify="android.intent.class.DEFAULT" />

17 <class android:identify="android.intent.class.BROWSABLE" />

18 <knowledge android:scheme="peoplesapp" />

19 </intent-filter>

20</exercise>

After this configuration step, rebuild your Android app utilizing npx react-native run-android.

Testing the iOS app

🔗

To check out the configuration you could have arrange to this point, run the iOS app, and open up the iOS simulator. If the instance app is already working, shut it earlier than testing.

Then, from a terminal window, run the next command:

xcrun simctl openurl booted peoplesapp://

npx uri-scheme open peoplesapp:// --ios

It will open the instance app:

js4

You can even check it by opening up an online browser in your simulator system and working the URL peoplesapp://. It’ll ask you as to whether open the exterior URI or not, as proven under:

js5

Testing the Android app

🔗

To check out the configuration arrange to this point, I’m utilizing an actual Android system. You can even use an Android emulator. Be sure to shut the instance app whether it is already working earlier than testing.

From a terminal window, run the next command:

adb shell am begin -W -a android.intent.motion.VIEW -d "peoplesapp://"

npx uri-scheme open peoplesapp:// --android

Right here is the output after working the above command:

js6

Nested display configuration

🔗

You possibly can prolong the linking config object to outline a selected path for every display. That is helpful, particularly when you could have a number of screens and hyperlink to every particular display.

Within the instance app, let’s outline linking paths for each the Residence and Particulars display. Modify the linking config object within the src/navigation/RootNavigator.js file as proven under:

1const linking = {

2 prefixes: ['peoplesapp://'],

3 config: {

4 initialRouteName: 'Residence',

5 screens: {

6 Residence: {

7 path: 'house'

8 },

9 Particulars: {

10 path: 'particulars'

11 }

12 }

13 }

14};

The initialRouteName is the identify of the preliminary display. The again button will not be proven by default when linking to a nested display. Utilizing the property, you may outline a display identify to return, inside the app.

The screens property maps display names to display paths. The display path is the trail that’s used to hyperlink to the display.

Now, let’s try it out. Be sure to give up the app earlier than testing.

js7

The display path configuration works as anticipated.

Accessing dynamic parameters in a route

🔗

To show info of every particular person when visiting the Particulars display with the URL scheme, you must configure the path for the Particulars display and add a dynamic parameter that represents the particular person’s id from the listing.

1const linking = {

2 prefixes: ['peoplesapp://'],

3 config: {

4 initialRouteName: 'Residence',

5 screens: {

6 Residence: {

7 path: 'house'

8 },

9 Particulars: {

10 path: 'particulars/:personId'

11 }

12 }

13 }

14};

The personId is now accessible to the Particulars display as a route paramater. Route parameters are accessible to a display utilizing route.params from React Navigation library.

Based mostly on the personId worth, the Particulars display will fetch the information from the API and show the particular person’s info.

Let’s additionally deal with the case the place an app person navigates to the Particulars display from the Residence display, that’s, with out utilizing linking. On this case, open HomeScreen.js and change the worth onPress prop on the Pressable part as proven under:

1

2

3<Pressable

4 onPress={() => navigation.navigate('Particulars', { personDetailsId: merchandise.id })}

5 fashion={{ paddingHorizontal: 10 }}

6>

7 <Textual content fashion={{ fontSize: 24, coloration: '#000' }}>{merchandise.identify}</Textual content>

8</Pressable>

Discover that the personDetailsId is a route parameter handed to the Particulars display within the above snippet. It will solely fetch an individual’s particulars when the person navigates to the Particulars display from the Residence display.

Within the Particulars display, let’s get each personDetailsId (the id coming from the Residence display) and personId (the id used from the URL scheme) from the route.params object.

Then utilizing a useEffect hook, fetch knowledge from Json Placeholder API and render the main points:

1import React, { useState, useEffect } from 'react';

2import { View, Textual content, ActivityIndicator } from 'react-native';

3

4const DetailsScreen = ({ route }) => {

5 const params = route.params || {};

6 const { personDetailsId, personId } = params;

7

8 const [data, setData] = useState([]);

9 const [isLoading, setIsLoading] = useState(true);

10

11 useEffect(() => {

12 if (personId) {

13 fetch(`https://jsonplaceholder.typicode.com/customers/${personId}`)

14 .then(res => res.json())

15 .then(res => {

16 const fetchedDetails = [];

17

18 Object.keys(res).forEach(key => {

19 fetchedDetails.push({ key, worth: `${res[key]}` });

20 });

21 setData(fetchedDetails);

22 setIsLoading(false);

23 })

24 .catch(error => {

25 console.log(error);

26 });

27 } else {

28 fetch(`https://jsonplaceholder.typicode.com/customers/${personDetailsId}`)

29 .then(res => res.json())

30 .then(res => {

31 const fetchedDetails = [];

32

33 Object.keys(res).forEach(key => {

34 fetchedDetails.push({ key, worth: `${res[key]}` });

35 });

36

37 setData(fetchedDetails);

38 setIsLoading(false);

39 })

40 .catch(error => {

41 console.log(error);

42 });

43 }

44 }, []);

45

46 return (

47 <View fashion={{ flex: 1 }}>

48 {isLoading ? (

49 <ActivityIndicator coloration="blue" measurement="massive" />

50 ) : (

51 <View fashion={{ paddingTop: 10, paddingHorizontal: 10 }}>

52 {knowledge.map(particular person => (

53 <Textual content

54 fashion={{ fontSize: 24, paddingBottom: 2 }}

55 key={particular person.key}

56 >{`${particular person.key}: ${particular person.worth}`}</Textual content>

57 ))}

58 </View>

59 )}

60 </View>

61 );

62};

63

64export default DetailsScreen;

Right here is the output while you navigate from the Residence to Particulars display by urgent on an individual’s identify from the listing:

js8

Right here is the output when utilizing the URL scheme:

js9

Conclusion

🔗

You will have now completed an entire demo of a React Native app that handles deep linking utilizing React Navigation library.

Deep linking can carry important enhancements to the person expertise of your cellular apps and allow engines like google to offer context-sensitive searches and outcomes. Hopefully, this information will enable you obtain nice leads to your individual app.


I am a software program developer and a technical author. On this weblog, I write about Technical writing, Node.js, React Native and Expo.

At the moment, working at Expo. Beforehand, I’ve labored as a Developer Advocate, and Senior Content material Developer with corporations like Draftbit, Vercel and Crowdbotics.

RELATED ARTICLES

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Most Popular

Recent Comments