# Usage

## Initialize provider in root of your app

```ts
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
:::

## Links module

### Use values from context (Expo Router)

SDK exposes `useDetourContext()` hook that returns object containing information about 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. Deep links based on uri-scheme are also supported.

```ts
import { useDetourContext } from '@swmansion/react-native-detour';
import * as SplashScreen from 'expo-splash-screen';
import { Stack, usePathname, useRouter } from 'expo-router';

SplashScreen.preventAutoHideAsync();

const normalizePath = (route: string) => route.split('?')[0] || '/';

export function RootNavigator() {
  const { isLinkProcessed, linkRoute, clearLink } = useDetourContext();
  const pathname = usePathname();
  const router = useRouter();

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

  useEffect(() => {
    if (!isLinkProcessed || !linkRoute) return;
    if (pathname !== normalizePath(linkRoute)) {
      router.replace(linkRoute);
      return;
    }
    clearLink(); // avoid redirecting again when returning to this screen
  }, [clearLink, isLinkProcessed, linkRoute, pathname, router]);

  if (!isLinkProcessed) {
    return null;
  }

  return <Stack />;
}
```

**linkRoute format**

`linkRoute` is a ready-to-use path (including query string if present).

Example:

```
URL:   https://example-organization.godetour.link/Ar8UqUjGzG/segment1?param1=value1
route: /segment1?param1=value1
```

**Short links**

If the incoming link path has a single segment (for example
`https://example-organization.godetour.link/Ar8UqUjGzG`), the SDK resolves it
to the full link before computing `linkRoute`.

**Custom schemes**

For custom scheme links, the route is computed from the host + pathname + query.
Example: `myapp://promo/123?utm=1` → `/promo/123?utm=1`.

### Implementation & lifecycle details

- On first app launch after install, the SDK checks whether this is the first entrance
  and attempts deferred matching once per session.
- If the app is opened via a Universal/App Link on first launch, the SDK handles that
  link immediately and skips deferred matching.
- `useDetourContext()` exposes the final state. Wait for `isLinkProcessed` before routing.
- Matching is asynchronous. Show a loading state while it runs.
- Clipboard matching (iOS) can be controlled via `Config.shouldUseClipboard`.
- After handling a route, call `clearLink()` to prevent repeated redirects.
- On subsequent launches the SDK checks only for Universal/App Links and processes them.

### Universal and App Links with Expo Router

Expo Router handles Universal/App Links on its own and may redirect to a route before the SDK finishes processing the link. The detected route can include the hash fragment Detour uses for link identification, so either match such routes in your navigation or add a catch-all.

Links resolve asynchronously, so without a catch-all Expo Router may show *Not Found* route for unknown paths while Detour resolves the final destination. Use a catch-all route to keep the user on a loading screen until Detour provides `linkRoute`:

```ts
// app/[...link].tsx
import { useDetourContext } from '@swmansion/react-native-detour';
import { useEffect } from 'react';
import { useRouter } from 'expo-router';

export default function CatchAllRoute() {
  const { isLinkProcessed, linkRoute } = useDetourContext();
  const router = useRouter();

  useEffect(() => {
    if (!isLinkProcessed) return;
    if (linkRoute) {
      router.replace(linkRoute);
    } else {
      router.replace('/');
    }
  }, [isLinkProcessed, linkRoute, router]);

  return null;
}
```

This keeps the UX consistent and avoids a flash of the Not Found screen.

## Analytics module

You can log specific user behaviors using the `DetourAnalytics` module. This allows you to
track the user journey through your conversion funnel.

Events are emitted via a global internal system and handled by the `DetourProvider`.

### Example usage

```ts
import { DetourAnalytics } from '@software-mansion-labs/react-native-detour';

// Simple event logging
DetourAnalytics.logEvent("login");

// Event logging with custom metadata
DetourAnalytics.logEvent('purchase', {
  item: 'subscription_premium',
  currency: 'USD',
});
```

:::caution[Use exactly one DetourProvider]
To ensure accurate event tracking and avoid duplicate logs, make sure your application
is wrapped in exactly one DetourProvider.
:::

Check the list of defined events [here](https://detour.swmansion.com/docs/sdk/react-native/0.6.x/api-reference#detoureventnames)