> ## Documentation Index
> Fetch the complete documentation index at: https://stytch.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Deep Linking

> Enable deeplinks in your React-Native project for Expo managed or bare (or vanilla) workflows.

<Tabs>
  <Tab title="Expo" icon="chevron-up">
    <Note>
      For an in-depth guide to deeplinking with Expo, [refer to the Expo docs](https://docs.expo.dev/guides/linking/#linking-to-your-app).

      Below is a summary of the steps required:
    </Note>

    <Steps>
      <Step title="Declare your app scheme in app.json">
        ```json theme={null}
        {
          "expo": {
            "scheme": "myapp"
          }
        }
        ```
      </Step>

      <Step title="Create the base URL">
        Use `Linking.createUrl()` from the expo-linking package to create the base URL you will pass into the `login_magic_link_url` and `signup_magic_link_url` params for calls to initiate magic links. `Linking.createUrl()` will return `exp://127.0.0.1:19000` for Expo apps in development, `exp://exp.host/@community/with-webbrowser-redirect` for apps published in Expo Go, and `myapp://` for published apps. This way, you can pass the value returned by `Linking.createUrl()` into `stytchClient.magiclinks.email.loginOrCreate` and it will work for both development and production cases. Your initiate call will look something like this:

        ```js theme={null}
        const baseUrl = Linking.createUrl();
        const magicLinkBaseUrl = baseUrl + '/authenticate';
        stytchClient.magicLinks.email.loginOrCreate('email', {
          login_magic_link_url: magicLinkBaseUrl,
          login_expiration_minutes: 60,
          signup_magic_link_url: magicLinkBaseUrl,
          signup_expiration_minutes: 60,
        });
        ```
      </Step>

      <Step title="Handle the deep link">
        In the above use case, when a user clicks the magic link in their email, they will be redirected to the route you passed in, with a token attached as a query parameter. You will then use the token from the query param to authenticate your user with `stytchClient.magicLinks.authenticate(token, {session_duration_minutes: 60});` For detailed information on handling deep links into your Expo app, check out the [Expo docs here](https://docs.expo.dev/guides/linking/#handling-links-into-your-app). An example using react-navigation could look like this:

        ```js theme={null}
        type RootStackParamList = {
          Home: undefined,
          Authenticate: { token: string }
        }
        type AuthenticateScreenProps = NativeStackScreenProps<RootStackParamList, 'Authenticate'>;
        const AuthenticateScreen: React.FC = ({ route }: AuthenticateScreenProps) => {
          React.useEffect(() => {
              stytch.magicLinks.authenticate(
                route.params.token,
                { session_duration_minutes: 60 })
                .then((res) => {
                  // do something with user/session data
                })
                .catch((e) => {
                  // handle error
                })
            }
          }, []);
        }
        ```
      </Step>
    </Steps>
  </Tab>

  <Tab title="Vanilla" icon="atom">
    <Note>
      For an in-depth guide to deeplinking with bare React Native projects, refer to the [React Native docs](https://reactnavigation.org/docs/deep-linking/#set-up-with-bare-react-native-projects).

      Below is a summary of the steps required:
    </Note>

    <Tabs>
      <Tab title="iOS" icon="apple">
        <Steps>
          <Step title="Add the following to AppDelegate.m">
            ```objc theme={null}
              // 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];
              }
            ```
          </Step>

          <Step>
            If your app is using Universal Links you'll need to add the following code as well:

            ```objc theme={null}
              // 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];
              }
            ```
          </Step>

          <Step title="Add the scheme to your project configuration">
            The easiest way to do this is with the uri-scheme package by running the following:

            ```bash theme={null}
              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.
          </Step>

          <Step title="Setup Associated Domains">
            To make sure Universal Links work in your app, you will also need to setup [Associated Domains](https://developer.apple.com/documentation/Xcode/supporting-associated-domains) on your server.
          </Step>

          <Step>
            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:

            ```objc theme={null}
            pod 'React', :path => 'docs/node_modules/react-native', :subspecs => [
              . . . // other subspecs
              'RCTLinkingIOS',
              . . .
            ]
            ```
          </Step>
        </Steps>
      </Tab>

      <Tab title="Android" icon="android">
        <Steps>
          <Step title="Configure external linking in Android">
            To configure external linking in Android, you create a new intent in the manifest.

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

            ```bash theme={null}
            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:

            1. 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).
            2. Add the new `<intent-filter>` inside the `MainActivity` entry with a `View` type action:

            ```xml theme={null}
            <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>
            ```
          </Step>

          <Step title="Verify Android App Links">
            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:

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

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

            After adding them it should look like this:

            ```xml theme={null}
            <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>
            ```
          </Step>

          <Step title="Declare the association between your website and your intent filters">
            Lastly, [declare the association](https://developer.android.com/training/app-links/configure-assetlinks#declare-website) between your website and your intent filters by hosting a Digital Asset Links JSON file.
          </Step>
        </Steps>
      </Tab>
    </Tabs>

    ### Testing

    To test deeplinking functionality before integrating and testing Stytch's EML product, refer to [this section of the React Native deeplinking docs](https://reactnavigation.org/docs/deep-linking/#testing-deep-links).
  </Tab>
</Tabs>
