# Usage

### Initialize provider in root of your app

```js
import { DetourProvider, type Config } from "@swmansion/react-native-detour";

const config: Config = {
  API_KEY: "<REPLACE_WITH_YOUR_API_KEY>",
  appID: "<REPLACE_WITH_APP_ID_FROM_PLATFORM>",
  shouldUseClipboard: true,
};

export default function RootLayout() {
  return (
    <DetourProvider config={config}>
      <RootNavigator />
    </DetourProvider>
  );
}
```

:::caution[Keep credentials in .env]
Keep your API_KEY and appID in .env
:::

### Use values from context - Example with Expo Router

SDK exposes `useDetourContext()` hook that returns object containing information about deferred link and processing status. Our recommendation is to use the hook before you application renders navigation container.

The SDK only looks for a deferred link during the application's first launch after installation. Subsequent launches should be handled by Universal Links for iOS and App Links for Android.

```js
import { useDetourContext } from "@swmansion/react-native-detour";
import * as SplashScreen from "expo-splash-screen";
import { Redirect, Stack } from "expo-router";

SplashScreen.preventAutoHideAsync();

export function RootNavigator() {
  const { deferredLinkProcessed, deferredLink, route } = useDetourContext();

  useEffect(() => {
    if (deferredLinkProcessed) {
      SplashScreen.hide();
    }
  }, [deferredLinkProcessed]);

  if (!deferredLinkProcessed) {
    return null;
  }

  if (route) {
    return <Redirect href={route} />;
  }

  return <Stack />;
}
```

### Implementation & lifecycle details (important for integrators)

- On first app launch after install:
  - provider checks `AsyncStorage` / persisted flag to determine "first entrance".
  - provider sets an in-memory flag (so remounts in the same process won't trigger extra runs).
  - provider will either:
    - use `clickId` (if Android install referrer is present) → deterministic match
    - or build `ProbabilisticFingerprint` → probabilistic match
- The hook (`useDetourContext()`) exposes the final state. Wait for `deferredLinkProcessed` before you attempt to route the user.
- Matching is asynchronous. Show a loading state while it runs, then route to the matched content.
- Clipboard: including `pastedLink` improves match accuracy but may surface a paste permission prompt (iOS). Make this configurable in `Config.shouldUseClipboard` for UX control.

### Universal and App Links handling

Expo Router handles Universal Links and App Links natively. When it detects that the app was opened by such a link, it redirects to the corresponding route before the SDK can process the link.

If your are not using Expo Router you need to process universal/app link which opened your app manually or upgrade to version 0.4.0 which gives you universal/app link value in same response what is used for deferred links.

**Important**: Remember that the route detected by Expo Router will contain the necessary **hash** that Detour uses for link identification. You must either match this route within your navigation structure or implement a catch-all mechanism for unassigned routes in your application.

Example implementation of `app/[...unmatched].tsx`:

```js
export default function UnmatchedRoute() {
  // 1. Get the current path that Expo Router is trying to render
  // Example: "/abcd-1234/product/5"
  const pathname = usePathname();

  // 2. Parse it
  const cleanPath = stripHashAndParseUrl(pathname);

  // 3. Safety Check:
  if (cleanPath === pathname || cleanPath === "/") {
    return <Redirect href="/" />;
  }

  // 4. Immediate Redirect to the clean path
  // e.g. Redirects to "/product/5"
  return <Redirect href={cleanPath} />;
}
```