Deep linking allows you to direct users to specific locations within your app using URLs. In this guide, we will set up deep linking for both a React and React Native application, along with setting up NGROK for testing and creating keystores for Android.
Let’s get started!🚀🚀
🌱Setting Up the React Project
1. Create a Vite React App:
npm create vite@latest my-app --template react
cd my-app
npm install
npm run dev
2. Add Deep Linking Logic:
Update the App.js
file:
import { useEffect } from "react";
import viteLogo from "/vite.svg";
import "./App.css";
function App() {
useEffect(() => {
const userAgent = navigator.userAgent || navigator.vendor || window.opera;
console.log("userAgent>>", userAgent);
if (/android/i.test(userAgent)) {
window.location.href = "YOUR_PLAY_STORE_URL";
} else if (/iPad|iPhone|iPod/.test(userAgent) && !window.MSStream) {
window.location.href = "YOUR_APP_STORE_URL";
}
}, []);
return (
<div className="App">
<header className="App-header">
<img src={viteLogo} className="App-logo" alt="logo" />
<p>Let's start Deep Linking :) :p</p>
</header>
</div>
);
}
export default App;
3. Set Up NGROK for Testing:
Note:- you can find the below commands on ngrock website
- Install NGROK:
brew install ngrok
- Configure NGROK with your authentication token:
ngrok config add-authtoken <your_auth_token>
- Start NGROK for your local server:
ngrok http http://localhost:8080
- NGROK will generate a public URL. Use this URL for testing your deep linking functionality.
đź› Setting Up Android Keystore
đź“ť Note:- add this command inside the android dir
1. Generate a Debug Keystore:
add this command inside the android dir by cd android
keytool -genkey -v -keystore debug.keystore -storepass android -alias androiddebugkey -keypass android -keyalg RSA -keysize 2048 -validity 10000
Details:
- Keystore Name:
debug.keystore
- Keystore Password:
android
- Key Alias:
androiddebugkey
- Key Password:
android
2. Generate a Release Keystore:
keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
3. Retrieve Keystore Fingerprints:
keytool -list -v -keystore <your_keystore_file> -alias <your_key_alias>
This command will output fingerprints like:
Certificate fingerprints:
SHA1: 04:11:15:B7:0F:C3:B0:3E:36:41:97:3A:E1:FD:E9:85:72:94:E4:33
SHA256: 28:1D:3F:4E:4F:E9:3E:6E:3D:9B:77:09:98:AE:9C:25:CF:D9:97:C5:A1:88:7D:F4:00:88:DA:9A:BE:A6:BE:77
⚙️Configuring Deep Linking
📱Android
1. Modify the Android Manifest File:
Add the following intent filter:
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="ADD_YOUR_URL" />
</intent-filter>
2. Add assetlinks.json
in the React Project:
- Create a
.well-known
folder inside the public directory. - Add an
assetlinks.json
file: - Add your fingerprint here
[
{
"relation": ["delegate_permission/common.handle_all_urls"],
"target": {
"namespace": "android_app",
"package_name": "package_name",
"sha256_cert_fingerprints": [
"04:11:15:B7:0F:C1:B0:3E:36:41:97:3A:E1:FD:E9:85:72:94:E4:33",
"28:1D:3F:4E:4F:E9:3E:6E:0D:9B:77:09:98:AE:9C:25:CF:D9:97:C5:A1:88:7D:F4:00:88:DA:9A:BE:A6:BE:77"
]
}
}
]
🍎iOS
1. Configure Associated Domains:
- Navigate to
Signing & Capabilities
in Xcode. - Add the
applinks domain
:
applinks:YOUR_DOMAIN_URL_WITHOUT_WWW_AND_HTTPS
- If the option is not visible, add it using the
+ Capability
button.
2. Add apple-app-site-association File:
Create an apple-app-site-association
file in the .well-known
folder:
{
"applinks": {
"apps": [],
"details": [
{
"appID": "TEAM_ID.bundle_id",
"components": [
{
"/": "*",
"?": {
"$web_only": "true"
},
"exclude": true,
"comment": "Matches any URL whose path is * and which has a query item with name '$web_only' and value 'true' and instructs the system NOT to open it as a Universal link"
},
{
"/": "*",
"?": {
"%24web_only": "true"
},
"exclude": true,
"comment": "Matches any URL whose path is * and which has a query item with name '%24web_only' and value 'true' and instructs the system NOT to open it as a Universal link"
},
{
"/": "/e/*",
"exclude": true,
"comment": "Matches any URL whose path is /e/* and instructs the system NOT to open it as a Universal link"
},
{
"/": "*",
"comment": "Matches any URL whose path is * and instructs the system to open it as a Universal link"
},
{
"/": "/",
"comment": "Matches any URL whose path is / and instructs the system to open it as a Universal link"
}
]
}
]
}
}
Replace TEAM_ID
with your Apple Developer Team ID and bundle_id
with your app’s bundle identifier.
TEAM_ID
bundle_id
Setting up for iOS
open AppDelegate.m
in root folder and add import following header:
#import “React/RCTLinkingManager.h”
And then add this code above @end.
NOTE: On iOS, you'll need to add the LinkingIOS folder into your header search paths as described in step 3 here. If you also want to listen to incoming app links during your app's execution, you'll need to add the following lines to your
AppDelegate.m
:
// iOS 9.x or newer
#import <React/RCTLinkingManager.h>
- (BOOL)application:(UIApplication *)application
openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
return [RCTLinkingManager application:application openURL:url options:options];
}
If you're targeting iOS 8.x or older, you can use the following code instead:
// iOS 8.x or older
#import <React/RCTLinkingManager.h>
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
return [RCTLinkingManager application:application openURL:url
sourceApplication:sourceApplication annotation:annotation];
}
If your app is using Universal Links, you'll need to add the following code as well:
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity
restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
return [RCTLinkingManager application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
}
🧑‍💻Handling Deep Links in React Native
In React Native, you can handle deep links using the Linking
API. This allows you to listen for incoming deep links and navigate to the appropriate screen.
Set Up Deep Link Handling:
import React, { useEffect, useState } from 'react';
import { View, Text, Linking } from 'react-native';
const App = () => {
const [initialUrl, setInitialUrl] = useState(null);
useEffect(() => {
// Check if the app was opened with a deep link
const getInitialLink = async () => {
const url = await Linking.getInitialURL();
if (url) {
setInitialUrl(url);
}
};
getInitialLink();
// Listen for deep links while the app is running
const handleDeepLink = (event) => {
console.log('Deep link URL:', event.url);
// Handle navigation based on the URL
};
Linking.addEventListener('url', handleDeepLink);
// Cleanup event listener
return () => {
Linking.removeEventListener('url', handleDeepLink);
};
}, []);
return (
<View>
<Text>Welcome to Deep Linking Demo</Text>
{initialUrl ? <Text>Initial URL: {initialUrl}</Text> : null}
</View>
);
};
export default App;
Explanation:
-
Linking.getInitialURL():
This gets the URL that the app was opened with (i.e., when the app is launched from a deep link). -
Linking.addEventListener('url', handleDeepLink):
This listens for incoming deep links while the app is running in the background or the foreground.
🧪Testing Deep Linking
- Start the NGROK server and verify that your .well-known folder and files are accessible via the public URL.
- Test deep linking by opening your app through the NGROK URL.
- Verify that the app opens the appropriate sections based on the URL
🎯 Conclusion
Deep linking improves user experience by providing direct navigation to specific app content. By following this guide, you’ve set up deep linking for both React and React Native applications, tested with NGROK, and configured keystores for Android signing.
Top comments (0)