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

# React Native Deep Linking for SocketFi Authentication

> Configure your Expo app scheme and expo-linking listener so SocketFi can redirect users back to your app after passkey authentication.

Deep linking is the mechanism that brings users back to your app after they complete authentication or approve a transaction in the SocketFi hosted browser. When the user finishes the flow, SocketFi redirects their browser to a URL like `myapp://socketfi/auth/success`. Your app intercepts that URL, extracts any result data, and resumes the user's session.

<Warning>
  Without deep linking configured, users will complete passkey authentication successfully in the browser but have no way to return to your app. They will be stuck in the browser with a blank or completed screen. Deep linking is not optional — it is required for the React Native SDK to function.
</Warning>

## Why deep linking is required

Mobile browsers do not support the popup window pattern used by the React SDK. Instead, the React Native SDK opens a full in-app browser session (`expo-web-browser`), hands control to SocketFi's hosted flow, and relies on a custom URL scheme to pass control back when done. This is the standard OAuth-style redirect pattern for mobile apps.

## Step 1 — Register your app scheme

Open your `app.json` and add a `scheme` field inside the `expo` object:

```json app.json theme={null}
{
  "expo": {
    "name": "Acme Pay",
    "slug": "acme-pay",
    "scheme": "acmepay"
  }
}
```

The value you choose for `scheme` must be:

* All lowercase
* No spaces or special characters (hyphens are acceptable)
* Unique to your app — generic schemes like `app` or `myapp` can collide with other apps on a user's device

After setting the scheme, rebuild your native app (`npx expo run:ios` or `npx expo run:android`) so the scheme is registered with the OS. Changes to `app.json` are not picked up by Expo Go hot-reload.

## Step 2 — Understand the deep link URL format

SocketFi uses the following URL patterns to communicate the result of a hosted flow back to your app:

| Event                              | Deep link URL                          |
| ---------------------------------- | -------------------------------------- |
| Authentication succeeded           | `myapp://socketfi/auth/success`        |
| Authentication failed or cancelled | `myapp://socketfi/auth/error`          |
| Transaction approved               | `myapp://socketfi/transaction/success` |
| Transaction rejected               | `myapp://socketfi/transaction/error`   |

Replace `myapp` with the `scheme` value you registered in `app.json`.

## Step 3 — Set up the expo-linking event listener

Register a URL listener early in your app's lifecycle — typically in your root component or navigation container — so SocketFi deep links are caught as soon as they arrive.

```typescript App.tsx theme={null}
import { useEffect } from "react";
import * as Linking from "expo-linking";

function useSocketFiDeepLinks() {
  useEffect(() => {
    // Handle deep links that arrive while the app is already open
    const subscription = Linking.addEventListener("url", ({ url }) => {
      handleSocketFiUrl(url);
    });

    // Handle the URL that launched the app from a cold start
    Linking.getInitialURL().then((url) => {
      if (url) {
        handleSocketFiUrl(url);
      }
    });

    return () => subscription.remove();
  }, []);
}

function handleSocketFiUrl(url: string) {
  const { path } = Linking.parse(url);

  if (path === "socketfi/auth/success") {
    console.log("Authentication completed — session will be set by SDK callback");
  } else if (path === "socketfi/auth/error") {
    console.warn("Authentication failed or was cancelled via deep link");
  } else if (path === "socketfi/transaction/success") {
    console.log("Transaction approved");
  } else if (path === "socketfi/transaction/error") {
    console.warn("Transaction rejected or failed");
  }
}
```

<Note>
  The SocketFi SDK resolves the `authenticate()` Promise automatically when the deep link arrives — you don't need to manually extract session data from the URL. The listener is useful for side effects like analytics, navigation, or showing toasts.
</Note>

## Step 4 — Wire the hook into your root component

Call `useSocketFiDeepLinks()` at the top of your root component so the listener is registered before any navigation occurs:

```typescript App.tsx theme={null}
import { useEffect } from "react";
import * as Linking from "expo-linking";
import { View } from "react-native";
import { AuthProvider } from "./lib/AuthProvider";
import { RootNavigator } from "./navigation/RootNavigator";

function useSocketFiDeepLinks() {
  useEffect(() => {
    const subscription = Linking.addEventListener("url", ({ url }) => {
      const { path } = Linking.parse(url);
      if (path?.startsWith("socketfi/")) {
        // SDK handles the resolution; add any side effects here
        console.log("SocketFi deep link received:", path);
      }
    });

    Linking.getInitialURL().then((url) => {
      if (url) {
        const { path } = Linking.parse(url);
        if (path?.startsWith("socketfi/")) {
          console.log("App launched via SocketFi deep link:", path);
        }
      }
    });

    return () => subscription.remove();
  }, []);
}

export default function App() {
  useSocketFiDeepLinks();

  return (
    <AuthProvider>
      <RootNavigator />
    </AuthProvider>
  );
}
```

## Testing deep links

You can test that your scheme is registered correctly using the Expo CLI or `adb`/`xcrun` without going through a full authentication flow.

<Tabs>
  <Tab title="Expo CLI">
    ```bash theme={null}
    # Simulate the auth success deep link
    npx uri-scheme open "acmepay://socketfi/auth/success" --ios
    npx uri-scheme open "acmepay://socketfi/auth/success" --android
    ```
  </Tab>

  <Tab title="iOS Simulator">
    ```bash theme={null}
    xcrun simctl openurl booted "acmepay://socketfi/auth/success"
    ```
  </Tab>

  <Tab title="Android Emulator">
    ```bash theme={null}
    adb shell am start \
      -W -a android.intent.action.VIEW \
      -d "acmepay://socketfi/auth/success"
    ```
  </Tab>
</Tabs>

If your listener logs the path, deep linking is configured correctly. If nothing happens, double-check that you rebuilt the native app after adding the `scheme` to `app.json`.

<Tip>
  During development with Expo Go, deep linking uses the `exp://` scheme rather than your custom scheme. Use a development build (`npx expo run:ios` or `npx expo run:android`) to test your custom scheme end-to-end.
</Tip>

## Common issues

| Issue                                        | Likely cause                                            | Fix                                                              |
| -------------------------------------------- | ------------------------------------------------------- | ---------------------------------------------------------------- |
| App doesn't open from browser redirect       | `scheme` not in `app.json` or native app not rebuilt    | Add `scheme` and run `npx expo run:ios` / `npx expo run:android` |
| Listener fires but `path` is `null`          | URL not matching expected format                        | Log the raw `url` and compare against the table above            |
| Works in Expo Go but not in production build | Scheme mismatch between `app.json` and EAS build config | Ensure `scheme` is consistent across `app.json` and `eas.json`   |
