Handling Deep Linking and URL Schemes
1. Configuring Deep Link Schemes
| Property | Description | Example |
|---|---|---|
| scheme | Defines the URL scheme for deep linking (e.g., 'myapp') | scheme: 'myapp' |
| host | Optional host name for the deep link (e.g., 'example.com') | host: 'example.com' |
| path | Optional path to append to the URL (e.g., '/home') | path: '/home' |
Example: Configuring Deep Link Schemes in Android
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="myapp" android:host="example.com" />
</intent-filter>
Example: Configuring Deep Link Schemes in iOS
let urlScheme = "myapp"
let host = "example.com"
// In Info.plist
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLName</key>
<string>com.myapp</string>
<key>CFBundleURLSchemes</key>
<array>
<string>myapp</string>
</array>
</dict>
</array>
2. Handling Incoming Links
| Property | Description | Example |
|---|---|---|
| Linking.addEventListener | Listen for incoming links | Linking.addEventListener('url', handleUrl); |
| Linking.getInitialURL | Get the URL that launched the app | const url = await Linking.getInitialURL(); |
| Linking.canOpenURL | Check if a URL can be opened by the app | const supported = await Linking.canOpenURL(url); |
Example: Handling Deep Links
import { Linking } from 'react-native';
const handleUrl = (event) => {
const url = event.url;
// Handle the URL here
console.log('Received URL:', url);
};
Linking.addEventListener('url', handleUrl);
// Get initial URL
Linking.getInitialURL().then((url) => {
if (url) {
console.log('Initial URL:', url);
}
});
Note: On iOS, you must configure URL schemes in your
Info.plist to receive deep links.
Warning: Ensure that your app handles URLs securely to prevent malicious navigation.
3. Parsing URL Parameters
| Parameter | Type | Description | Example |
|---|---|---|---|
| url | string |
The full URL string to parse | "myapp://user/123?name=john&age=30" |
| path | string |
The path portion of the URL | "user/123" |
| query | object |
Key-value pairs from the query string | {name: "john", age: "30"} |
Example: Parsing URL Parameters
import { Linking } from 'react-native';
const handleDeepLink = (url) => {
const { path, query } = Linking.parse(url);
console.log('Path:', path); // user/123
console.log('Query:', query); // { name: 'john', age: '30' }
};
Linking.addEventListener('url', handleDeepLink);
Note: The
Linking.parse() method is available in React Native v0.63 and above.
Warning: Query parameters are parsed as strings. Type conversion (e.g., age to number) must be handled manually.
4. Navigating from Deep Links
Example: Handling Deep Links in App
import { Linking } from 'react-native';
const handleDeepLink = (url) => {
if (url) {
const path = new URL(url).pathname;
// Navigate to specific screen based on path
navigation.navigate('Profile', { userId: path.split('/')[2] });
}
};
// Listen for deep link events
const subscription = Linking.addEventListener('url', handleDeepLink);
// Handle initial deep link
Linking.getInitialURL().then(url => handleDeepLink(url));
// Cleanup listener
return () => subscription.remove();
};
| Property | Description | Usage |
|---|---|---|
| Linking.addEventListener | Event listener for deep link URLs | Listen to URL changes from external sources |
| Linking.getInitialURL | Get URL that opened the app initially | Handle deep links on app launch |
| Linking.canOpenURL | Check if a URL can be opened by the app | Validate deep link before navigation |
Note: Ensure your app's URL scheme is properly configured in the native project files (Info.plist for iOS, AndroidManifest.xml for Android) to receive deep links.
5. Testing Deep Links
Testing Deep Links in React Native
- Set up a test environment with a mock deep link handler
- Use
Linking.canOpenURL()to verify URL schemes - Simulate deep link navigation using
Linking.openURL() - Test with different URL formats and query parameters
- Validate that the app navigates correctly to intended screens
| Test Method | Description | Code Example |
|---|---|---|
| canOpenURL | Checks if a URL can be opened by the app | |
| openURL | Opens a URL using the system handler | Linking.openURL('myapp://settings'); |
Example: Mock Deep Link Handler
import { Linking } from 'react-native';
const handleDeepLink = (url) => {
const { hostname, path, query } = Linking.parse(url);
if (hostname === 'myapp') {
// Handle specific paths
switch (path) {
case '/profile':
// Navigate to profile screen
break;
case '/settings':
// Navigate to settings screen
break;
default:
console.warn('Unknown deep link path:', path);
}
}
};
Note: Ensure that your app's URL scheme is registered in the native project configuration (Info.plist for iOS, AndroidManifest.xml for Android).
6. Implementing Universal Links
Universal Links are HTTP URLs that can open your app directly when installed, or fall back to a web page if not installed. They are supported on iOS and Android (with some limitations).
| Platform | Support | Notes |
|---|---|---|
| iOS | Full | Requires associated domains and app-specific configuration |
| Android | Partial | Requires intent filters and app links setup, limited support for deep linking |
Example: Setting up Universal Links in iOS
// In your app's Info.plist
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:yourdomain.com</string>
</array>
Example: Setting up App Links on Android
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter
android:autoVerify="true">
<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="yourdomain.com" />
</intent-filter>
</activity>
Note: Universal Links require a valid SSL certificate and proper configuration of the
apple-app-site-association file on your domain for iOS, and assetlinks.json for Android.
Warning: Make sure to test Universal Links on real devices, as they may not work correctly in simulators or emulators.
7. Implementing App Links
Example: Setting up App Links
// App.js
import React from 'react';
import { Linking } from 'react-native';
const handleDeepLink = (url) => {
console.log("Deep link received:", url);
// Handle the deep link logic here
};
const App = () => {
React.useEffect(() => {
const subscription = Linking.addEventListener('url', handleDeepLink);
return () => subscription.remove();
}, []);
return <View style={{ flex: 1 }}></View>;
};
export default App;
| Property | Description | Notes |
|---|---|---|
| Linking.canOpenURL() | Checks if a URL can be opened by the app | Returns a Promise<boolean> |
| Linking.openURL() | Opens a URL in the app or system browser | Throws error if URL is invalid |
| Linking.addEventListener() | Adds event listener for URL changes | Event name: "url" |
Note: For Android, ensure your
AndroidManifest.xml includes proper intent filters.
Warning: iOS requires configuring
LSApplicationQueriesSchemes in Info.plist.
8. Handling Link Opening
| Property | Description | Example |
|---|---|---|
| Linking.openURL() | Opens the URL in an external browser or app | Linking.openURL('https://example.com'); |
| Linking.canOpenURL() | Checks if a URL can be opened by the device | Linking.canOpenURL('https://example.com'); |
| Linking.getInitialURL() | Gets the URL that launched the app | Linking.getInitialURL(); |
Example: Opening a URL
import { Linking } from 'react-native';\n\nconst openURL = () => {\n Linking.openURL('https://example.com');\n};
Example: Checking URL Support
import { Linking } from 'react-native';\n\nconst checkURL = async () => {\n const supported = await Linking.canOpenURL('https://example.com');\n if (supported) {\n Linking.openURL('https://example.com');\n }\n};
Note: On iOS, you must configure URL schemes in
Info.plist to handle custom schemes.
Warning: Ensure that URLs are properly escaped to avoid security issues.
9. Creating Dynamic Links
Example: Setting up Firebase Dynamic Links
// firebase.js
import { initializeApp } from 'firebase/app';
import { getDynamicLinks } from 'firebase/dynamic-links';
const firebaseConfig = {
apiKey: "AIzaSy...",
authDomain: "myapp.firebaseapp.com",
projectId: "myapp",
storageBucket: "myapp.appspot.com",
messagingSenderId: "123456789",
appId: "1:123456789:web:abc123"
};
const app = initializeApp(firebaseConfig);
const dynamicLinks = getDynamicLinks(app);
export { dynamicLinks };
| Property | Description | Example Value |
|---|---|---|
| link | URL to be opened when the dynamic link is clicked | https://myapp.page.link/abc123 |
| domainUriPrefix | Domain URI prefix for the dynamic link | https://myapp.page.link |
| androidInfo | Android-specific configuration | { packageName: 'com.myapp' } |
| iosInfo | iOS-specific configuration | { bundleId: 'com.myapp.ios' } |
Example: Creating a Dynamic Link
// Create a dynamic link
import { buildShortLink } from 'firebase/dynamic-links';
const dynamicLink = await buildShortLink({
link: 'https://myapp.com/deeplink?param=value',
domainUriPrefix: 'https://myapp.page.link',
androidInfo: {
packageName: 'com.myapp'
},
iosInfo: {
bundleId: 'com.myapp.ios'
}
});
console.log(dynamicLink); // https://myapp.page.link/abc123
Note: Dynamic links can be used to deep link into your app from external sources like emails, SMS, or social media posts.
10. Debugging Deep Link Issues
Example: Logging Deep Link Events
import { Linking } from 'react-native';
// Log all deep link events
const handleDeepLink = (url) => {
console.log('Deep link received:', url);
};
Linking.addEventListener('url', handleDeepLink);
// For iOS, also listen to the 'open' event
if (Platform.OS === 'ios') {
Linking.addEventListener('open', handleDeepLink);
}
// For Android, also listen to the 'newIntent' event
if (Platform.OS === 'android') {
Linking.addEventListener('newIntent', handleDeepLink);
}
| Issue | Possible Cause | Solution |
|---|---|---|
| Deep link not opening app | URL scheme not registered in manifest | Check AndroidManifest.xml or Info.plist for correct URL scheme |
| Deep link opens app but not to correct screen | Incorrect route mapping in navigator | Verify deep link path matches navigation structure |
| Deep link not received in app | Event listener not attached properly | Ensure event listeners are added before app starts |
| Deep link URL not parsed correctly | Query parameters or path not handled | Use URL parsing libraries like query-string |
Note: On iOS, make sure to add the URL scheme to your app’s Info.plist under
CFBundleURLTypes.
Warning: On Android, ensure that the intent filter in
AndroidManifest.xml includes android:autoVerify="true" for better deep link handling.
Debugging Workflow
- Log all incoming deep links to console
- Verify URL scheme registration in app manifest
- Check that navigation is correctly set up to handle the deep link path
- Test with actual device or emulator using
adb shell am startcommand - Use React Native Debugger or Flipper to inspect state changes