Deep Linking

This process for enabling deeplinks in your project is different for Expo managed vs. bare (or vanilla) workflows.

For an in-depth guide to deeplinking with bare React Native projects, refer to the React Native docs.

While the React Native guide contains the full details, below is a summary of the steps required:

iOS Setup

  • Add the following to AppDelegate.m

    // Add the header at the top of the file:
    #import <React/RCTLinkingManager.h>
    
    // Add this above '@end':
    - (BOOL)application:(UIApplication *)application
        openURL:(NSURL *)url
        options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
    {
      return [RCTLinkingManager application:application openURL:url options:options];
    }
  • If your app is using Universal Links you'll need to add the following code as well:

    // Add this above '@end':
    - (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity
      restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
    {
      return [RCTLinkingManager application:application
                      continueUserActivity:userActivity
                        restorationHandler:restorationHandler];
    }
  • Add the scheme to your project configuration. The easiest way to do this is with the uri-scheme package by running the following:

    npx uri-scheme add myapp --ios

    If you want to do it manually, open the project (e.g. SimpleApp/ios/SimpleApp.xcworkspace) in Xcode. Select the project in sidebar and navigate to the info tab. Scroll down to "URL Types" and add a new one. In the new URL type, set the identifier and the URL scheme to your desired URL scheme.

  • To make sure Universal Links work in your app, you will also need to setup Associated Domains on your server.

  • If you're using React Navigation within a hybrid app - an iOS app that has both Swift/Objective-C and React Native parts - you may be missing the RCTLinkingIOS subspec in your Podfile, which is installed by default in new React Native projects. To add this, ensure your Podfile looks like the following:

    pod 'React', :path => 'docs/node_modules/react-native', :subspecs => [
      . . . // other subspecs
      'RCTLinkingIOS',
      . . .
    ]

Android Setup

To configure the external linking in Android, you create a new intent in the manifest.

The easiest way to do this is with the uri-scheme package:

npx uri-scheme add myapp --android

If you want to add it manually, open up SimpleApp/android/app/src/main/AndroidManifest.xml, and make the following adjustments:

  • Set launchMode of MainActivity to singleTask in order to receive intent on existing MainActivity (this is the default, so you may not need to actually change anything).

  • Add the new <intent-filter> inside the MainActivity entry with a View type action:

    <activity
        android:name=".MainActivity"
        android:launchMode="singleTask">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <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" />
        </intent-filter>
    </activity>

Similar to Universal Links on iOS, you can also use a domain to associate the app with your website on Android by Verifying Android App Links. First, you need to configure your AndroidManifest.xml:

  • Add android:autoVerify="true" to your <intent-filter> entry.

  • Add your domain's scheme and host in a new <data> entry inside the <intent-filter>

After adding them it should look like this:

<activity
    android:name=".MainActivity"
    android:launchMode="singleTask">
    <intent-filter android:autoVerify="true">
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    <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" />
        <data android:scheme="https" android:host="www.example.com" />
        <data android:scheme="http" android:host="www.example.com" />
    </intent-filter>
</activity>

Then, you need to declare the association between your website and your intent filters by hosting a Digital Asset Links JSON file.

Testing

To test deeplinking functionality before integrating and testing Stytch's EML product, refer to this section of the React Native deeplinking docs.