Skip to main content
Version: 2.0.0

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:

  1. Checks for an initial URL that launched the app (Universal/App Link on cold start)
  2. If no initial link is found, queries the Detour API for a deferred link (first install only)
  3. Attaches a runtime listener for Universal/App Links received while the app is running
  4. 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;

Web behavior

On Platform.OS === 'web', provider initialization is skipped — no link processing hooks run, no analytics listeners attach, and no storage is accessed. DetourProvider returns a no-op context value:

  • isLinkProcessed: true
  • link: null
  • clearLink: () => {}

In development builds, the SDK logs a single warning: [Detour:WEB_UNSUPPORTED]. This is safe to use in universal code shared between web and native.

Config fields

FieldTypeRequiredDefaultDescription
appIDstringYesUnique app identifier from the Detour dashboard. Used to authenticate API requests and route links to the correct app
apiKeystringYesPublishable API key from the Detour dashboard. Used as a Bearer token for all API calls (deferred link matching, short-link resolution, analytics)
shouldUseClipboardbooleanNotrueiOS 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
linkProcessingModeLinkProcessingModeNo'all'Controls which link sources the SDK processes. See LinkProcessingMode for details on each value
storageDetourStorageNoAsyncStorageCustom 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

PropertyTypeDescription
isLinkProcessedbooleantrue 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
linkDetourLinkResolved link data, or null if no link was detected. Persists until clearLink() is called
clearLink() => voidResets 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

Typestring
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

TypeArray<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

TypeDetourNativeIntentResolveConfig
Defaultundefined

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.

FieldTypeRequiredDefaultDescription
apiKeystringYesPublishable API key from the Detour dashboard (same value used in DetourProvider config)
appIDstringYesApp identifier from the Detour dashboard (same value used in DetourProvider config)
timeoutMsnumberNo1200Maximum time in milliseconds to wait for short-link resolution. If exceeded, fallbackPath is returned
onResolveError(error, context) => voidNoCallback invoked when resolution fails (e.g. network error, invalid link). Useful for logging or error reporting
DetourProvider configuration

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

ValueBehavior
'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:

ValueMeaning
'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
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.

FieldTypeDescription
urlstring | URLOriginal URL as parsed by the URL constructor, or raw string if parsing failed
routestringFull in-app route including query string (e.g. /details?utm=1). For web URLs, the first path segment (app hash) is stripped
pathnamestringPath without query string (e.g. /details). For web URLs, the first path segment (app hash) is stripped
paramsRecord<string, string>Query string parameters as a key-value record. All values are strings
typeLinkTypeHow the link arrived in the app

DetourContextType

type DetourContextType = {
isLinkProcessed: boolean;
link: DetourLink;
clearLink: () => void;
};

Shape of the value returned by useDetourContext.

PropertyTypeDescription
isLinkProcessedbooleantrue once the SDK has finished all link detection attempts. false during cold start processing
linkDetourLinkResolved link data or null. Persists until clearLink() is called
clearLink() => voidResets 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.

FieldTypeDescription
pathstringIncoming system path or URL from Expo Router
initialbooleantrue 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.

FieldTypeDescription
originalPathstringThe original incoming system path before resolution
initialbooleantrue if this is the initial URL that launched the app
resolvedUrlURLThe resolved destination URL after short-link resolution

DetourEventNames

CategoryEvent NameString Value
GeneralLoginlogin
Searchsearch
Shareshare
SignUpsign_up
TutorialBegintutorial_begin
TutorialCompletetutorial_complete
ReEngagere_engage
Inviteinvite
OpenedFromPushNotificationopened_from_push_notification
SalesAddPaymentInfoadd_payment_info
AddShippingInfoadd_shipping_info
AddToCartadd_to_cart
RemoveFromCartremove_from_cart
Refundrefund
ViewItemview_item
BeginCheckoutbegin_checkout
Purchasepurchase
AdImpressionad_impression