API Reference
DetourProvider
Top-level React component that initializes the Detour SDK. It manages the full link processing lifecycle — deferred link matching, Universal/App Link listening, initial URL handling, and analytics event transport.
On mount, the provider:
- Checks for an initial URL that launched the app (Universal/App Link on cold start)
- If no initial link is found, queries the Detour API for a deferred link (first install only)
- Attaches a runtime listener for Universal/App Links received while the app is running
- Subscribes to analytics events and forwards them to the Detour backend
Use exactly one DetourProvider at the root of your app tree. Multiple providers are detected at runtime and will cause analytics events to be dropped.
Signature
function DetourProvider(props: {
config: Config;
children: React.ReactNode;
}): JSX.Element;
Config fields
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
appID | string | Yes | — | Unique app identifier from the Detour dashboard. Used to authenticate API requests and route links to the correct app |
apiKey | string | Yes | — | Publishable API key from the Detour dashboard. Used as a Bearer token for all API calls (deferred link matching, short-link resolution, analytics) |
shouldUseClipboard | boolean | No | true | iOS only. When true, the SDK reads the device clipboard as part of probabilistic fingerprinting for deferred link matching. Set to false if your app lacks clipboard permissions or you want to skip clipboard access |
linkProcessingMode | LinkProcessingMode | No | 'all' | Controls which link sources the SDK processes. See LinkProcessingMode for details on each value |
storage | DetourStorage | No | AsyncStorage | Custom storage adapter for SDK persistence. The SDK stores a first-entrance flag (for deferred link matching) and a device ID (for analytics). Defaults to @react-native-async-storage/async-storage if installed |
useDetourContext
Hook that returns the current link processing state and resolved link payload from the nearest DetourProvider. Throws an error if called outside of a DetourProvider tree.
Signature
function useDetourContext(): DetourContextType;
Returned object
| Property | Type | Description |
|---|---|---|
isLinkProcessed | boolean | true once the SDK has finished all link detection attempts, regardless of whether a link was found. Use this to conditionally show a loading/splash screen during cold start |
link | DetourLink | Resolved link data, or null if no link was detected. Persists until clearLink() is called |
clearLink | () => void | Resets link to null. Call after handling navigation to prevent repeated redirects |
DetourAnalytics
Analytics module exported from the package root. Requires an active DetourProvider in the component tree — events are silently dropped if no provider is mounted.
Methods
logEvent
DetourAnalytics.logEvent(
eventName: DetourEventNames | `${DetourEventNames}`,
data?: any,
): void;
Records a user action or custom event and sends it to the Detour backend. Pass one of the predefined DetourEventNames or a custom string. The optional data parameter accepts arbitrary metadata (e.g. { itemId: '123', price: 49.99 }).
logRetention
DetourAnalytics.logRetention(retentionEventName: string): void;
Records a retention/lifecycle event for user engagement tracking. The SDK automatically logs an app_open retention event when DetourProvider mounts for the first time in a session.
Expo Router helper
Available under subpath import:
import { createDetourNativeIntentHandler } from '@swmansion/react-native-detour/expo-router';
Signature
function createDetourNativeIntentHandler(
options?: DetourNativeIntentOptions,
): DetourNativeIntentHandler;
Options
fallbackPath
| Type | string |
| Default | '' |
The in-app route path returned when an incoming URL matches a Detour host but resolve mode is not enabled or resolution fails. Set this to the route you want users to land on as a safe default — for example, '' for the home screen or '/welcome' for an onboarding screen.
hosts
| Type | Array<string | RegExp> |
| Default | [/\.godetour\.link$/i] |
Host-matching patterns that determine which incoming URLs the handler should process. Only URLs whose hostname matches at least one entry are intercepted; all other URLs pass through unchanged to Expo Router's default routing.
Use strings for exact domain matches or regular expressions for wildcard matching. The default pattern matches any subdomain of godetour.link (e.g. abc123.godetour.link). If you use a custom domain for your Detour links, add it here.
config
| Type | DetourNativeIntentResolveConfig |
| Default | undefined |
Providing this object enables resolve mode. In resolve mode the handler resolves Detour short links (e.g. https://abc123.godetour.link/xyz) to their full destination URLs before routing to the matched in-app screen. Without config, the handler operates in intercept mode — it matches Detour hosts and returns fallbackPath without resolving the link.
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
apiKey | string | Yes | — | Publishable API key from the Detour dashboard (same value used in DetourProvider config) |
appID | string | Yes | — | App identifier from the Detour dashboard (same value used in DetourProvider config) |
timeoutMs | number | No | 1200 | Maximum time in milliseconds to wait for short-link resolution. If exceeded, fallbackPath is returned |
onResolveError | (error, context) => void | No | — | Callback invoked when resolution fails (e.g. network error, invalid link). Useful for logging or error reporting |
When using resolve mode, set linkProcessingMode: 'deferred-only' in your DetourProvider config so the provider only handles deferred links while +native-intent.tsx handles Universal Links and App Links. See SDK Usage — Configure DetourProvider for native intent.
mapToRoute
| Type | (value: DetourNativeIntentResolvedValue) => string |
| Default | Built-in mapper that strips the first path segment (app hash) from multi-segment web URLs |
Custom function that transforms a resolved URL into an in-app route string. The function receives a DetourNativeIntentResolvedValue object containing the originalPath, initial flag, and the resolvedUrl.
Use this when your Detour link destinations don't map directly to your app's route structure — for example, if your link URLs contain a prefix segment that doesn't correspond to an in-app screen.
Types
LinkProcessingMode
type LinkProcessingMode = 'all' | 'web-only' | 'deferred-only';
Controls which link sources DetourProvider processes:
| Value | Behavior |
|---|---|
'all' (default) | Processes all link sources: deferred links from the Detour API, runtime Universal Links (iOS) / App Links (Android), the initial URL that launched the app, and custom scheme deep links (e.g. myapp://path) |
'web-only' | Same as 'all' but filters out custom scheme links. Only HTTP/HTTPS URLs (Universal Links and App Links) and deferred links are processed |
'deferred-only' | Only processes deferred links obtained from the Detour API. Disables the runtime link listener and skips the initial URL check. Recommended when Expo Router's +native-intent.tsx already handles runtime and initial URLs |
LinkType
type LinkType = 'deferred' | 'verified' | 'scheme';
Describes how the link arrived in the app:
| Value | Meaning |
|---|---|
'deferred' | The link was obtained from the Detour deferred-link API. This happens when a user who doesn't have the app installed clicks a Detour link, installs the app, and opens it — the SDK retrieves the original link from the backend on first launch |
'verified' | The link arrived as a Universal Link (iOS) or App Link (Android) — an HTTP/HTTPS URL that the OS verified belongs to your app and delivered directly to it |
'scheme' | The link arrived via a custom URL scheme (e.g. myapp://path). These are non-HTTP URLs that the OS routes to your app based on the registered scheme |
DetourLink
type DetourLink = {
url: string | URL;
route: string;
pathname: string;
params: Record<string, string>;
type: LinkType;
} | null;
Resolved link data, or null if no link was detected.
| Field | Type | Description |
|---|---|---|
url | string | URL | Original URL as parsed by the URL constructor, or raw string if parsing failed |
route | string | Full in-app route including query string (e.g. /details?utm=1). For web URLs, the first path segment (app hash) is stripped |
pathname | string | Path without query string (e.g. /details). For web URLs, the first path segment (app hash) is stripped |
params | Record<string, string> | Query string parameters as a key-value record. All values are strings |
type | LinkType | How the link arrived in the app |
DetourContextType
type DetourContextType = {
isLinkProcessed: boolean;
link: DetourLink;
clearLink: () => void;
};
Shape of the value returned by useDetourContext.
| Property | Type | Description |
|---|---|---|
isLinkProcessed | boolean | true once the SDK has finished all link detection attempts. false during cold start processing |
link | DetourLink | Resolved link data or null. Persists until clearLink() is called |
clearLink | () => void | Resets link to null. Call after navigating to prevent repeated redirects |
DetourStorage
interface DetourStorage {
getItem(key: string): Promise<string | null> | string | null;
setItem(key: string, value: string): Promise<void> | void;
removeItem?(key: string): Promise<void> | void;
}
Interface for custom storage adapters. The SDK persists a first-entrance flag (used for deferred link matching — only triggers on first app install) and a stable device ID (used for analytics). Methods can be synchronous or asynchronous.
By default, @react-native-async-storage/async-storage is used. Provide a custom adapter if you use a different storage solution (e.g. MMKV, Expo SecureStore). See Custom Storage for examples.
DetourNativeIntentArgs
type DetourNativeIntentArgs = {
path: string;
initial: boolean;
};
Arguments passed by Expo Router to the redirectSystemPath handler.
| Field | Type | Description |
|---|---|---|
path | string | Incoming system path or URL from Expo Router |
initial | boolean | true when this is the initial URL used to launch the app (cold start), false for runtime link events |
DetourNativeIntentHandler
type DetourNativeIntentHandler = (
args: DetourNativeIntentArgs,
) => string | Promise<string>;
Function signature returned by createDetourNativeIntentHandler. Takes the incoming path and returns the resolved in-app route (synchronously or as a promise).
DetourNativeIntentResolveConfig
type DetourNativeIntentResolveConfig = {
apiKey: string;
appID: string;
timeoutMs?: number;
onResolveError?: (error: unknown, context: DetourNativeIntentArgs) => void;
};
Configuration that enables resolve mode in createDetourNativeIntentHandler. See config option for field descriptions.
DetourNativeIntentOptions
type DetourNativeIntentOptions = {
fallbackPath?: string;
hosts?: Array<string | RegExp>;
config?: DetourNativeIntentResolveConfig;
mapToRoute?: (value: DetourNativeIntentResolvedValue) => string;
};
Options for createDetourNativeIntentHandler. See Options for detailed field descriptions.
DetourNativeIntentResolvedValue
type DetourNativeIntentResolvedValue = {
originalPath: string;
initial: boolean;
resolvedUrl: URL;
};
Object passed to the mapToRoute callback after short-link resolution.
| Field | Type | Description |
|---|---|---|
originalPath | string | The original incoming system path before resolution |
initial | boolean | true if this is the initial URL that launched the app |
resolvedUrl | URL | The resolved destination URL after short-link resolution |
DetourEventNames
| Category | Event Name | String Value |
|---|---|---|
| General | Login | login |
Search | search | |
Share | share | |
SignUp | sign_up | |
TutorialBegin | tutorial_begin | |
TutorialComplete | tutorial_complete | |
ReEngage | re_engage | |
Invite | invite | |
OpenedFromPushNotification | opened_from_push_notification | |
| Sales | AddPaymentInfo | add_payment_info |
AddShippingInfo | add_shipping_info | |
AddToCart | add_to_cart | |
RemoveFromCart | remove_from_cart | |
Refund | refund | |
ViewItem | view_item | |
BeginCheckout | begin_checkout | |
Purchase | purchase | |
AdImpression | ad_impression |