Skip to main content

Handling Deep Linking and URL 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'
<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>
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>
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);
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.
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.
  1. Set up a test environment with a mock deep link handler
  2. Use Linking.canOpenURL() to verify URL schemes
  3. Simulate deep link navigation using Linking.openURL()
  4. Test with different URL formats and query parameters
  5. 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
import { Linking } from 'react-native';

const url = 'myapp://profile/123';
Linking.canOpenURL(url).then(supported => {
  if (supported) {
    Linking.openURL(url);
  }
});
openURL Opens a URL using the system handler Linking.openURL('myapp://settings');
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).

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
// In your app's Info.plist
<key>com.apple.developer.associated-domains</key>
<array>
    <string>applinks:yourdomain.com</string>
</array>
<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.
// 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.
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.
// 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' }
// 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.
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

  1. Log all incoming deep links to console
  2. Verify URL scheme registration in app manifest
  3. Check that navigation is correctly set up to handle the deep link path
  4. Test with actual device or emulator using adb shell am start command
  5. Use React Native Debugger or Flipper to inspect state changes

Was this article helpful?