Deep links allow users to navigate directly to specific content within your app by clicking on a URL. There are two primary approaches to deep linking:

  1. HTTP/HTTPS Deep Links (including subdomains): URLs with http:// or https:// protocols that can open your app when clicked.
  2. Custom URI Schemes: URLs with a custom protocol like myapp:// that are registered to your app.

This guide covers how to implement both methods for React Native and Flutter applications.

HTTP/HTTPS Deep Linking with Subdomains

When using subdomains for deep linking, you can create a structured approach to handle different sections or features of your app.

React Native uses React Navigation for handling navigation and deep linking.

First, you need to modify your Android and iOS configurations to handle subdomain links.

Open your android/app/src/main/AndroidManifest.xml file and add the following inside the <activity> section:

<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" />
  <!-- For your main domain -->
  <data android:scheme="https" android:host="example.com" />
  <!-- For your subdomain -->
  <data android:scheme="https" android:host="app.example.com" />
  <!-- Add other subdomains as needed -->
  <data android:scheme="https" android:host="store.example.com" />
</intent-filter>

Step 2: Configure React Navigation

In your navigation configuration:

// App.js or your navigation configuration file
import { NavigationContainer } from "@react-navigation/native";
import { createStackNavigator } from "@react-navigation/stack";
import LinkRunner from "@linkrunner/react-native";

const Stack = createStackNavigator();

function App() {
    const linking = {
        prefixes: ["https://example.com", "https://app.example.com", "https://store.example.com"],
        config: {
            screens: {
                Home: "",
                Profile: "profile/:id",
                Store: {
                    path: "store/:category?",
                    parse: {
                        category: (category) => category || "all",
                    },
                },
                // For subdomain-specific routing
                "app.example.com": {
                    screens: {
                        AppSpecificScreen: ":id",
                    },
                },
                "store.example.com": {
                    screens: {
                        StoreSpecificScreen: ":id",
                    },
                },
            },
        },
    };

    return (
        <NavigationContainer linking={linking}>
            <Stack.Navigator>{/* Your screens */}</Stack.Navigator>
        </NavigationContainer>
    );
}

export default App;

Custom URI Schemes for Deep Linking

Custom URI schemes provide an alternative method for deep linking, allowing your app to handle URLs with a custom protocol like myapp://. While HTTP/HTTPS deep links are generally recommended for production apps, custom URI schemes can be useful in specific scenarios or for backward compatibility.

Step 1: Configure your app to handle custom URI schemes

Open your android/app/src/main/AndroidManifest.xml file and add the following inside the <activity> section:

<intent-filter>
  <action android:name="android.intent.action.VIEW" />
  <category android:name="android.intent.category.DEFAULT" />
  <category android:name="android.intent.category.BROWSABLE" />
  <!-- Your custom URI scheme -->
  <data android:scheme="myapp" />
</intent-filter>

Use adb for Android testing:

# Test HTTP/HTTPS deep links
adb shell am start -a android.intent.action.VIEW -d "https://app.example.com/profile/123" your.package.name

# Test custom URI scheme
adb shell am start -a android.intent.action.VIEW -d "myapp://profile/123" your.package.name