Skip to main content
Version: 0.4.x

API Reference

DetourProvider

DetourProvider is the top-level React component that initializes the deferred-linking session and exposes context for the rest of your app.

Signature

export function DetourProvider(props: {
config: Config;
children: React.ReactNode;
}): JSX.Element;

Props

PropertyTypeRequiredDescription
configConfigYesConfiguration object containing authentication and behavioral flags. See Config type for details.
childrenReact.ReactNodeYesYour app's component tree.

Config fields

FieldTypeRequiredDefaultDescription
API_KEYstringYes-The publishable API key from your Detour dashboard
appIDstringYes-App identifier issued by the platform
shouldUseClipboardbooleanNotrueWhether to check clipboard for deferred links. iOS-only
storageDetourStorageNoAsyncStorageStorage adapter for detecting first run. Should implement interface DetourStorage

Runtime behavior

On mount, DetourProvider initializes the deferred-linking flow. Internally it:

  • Ensures single-run matching — Uses persisted state (AsyncStorage) and an in-memory guard so matching runs only once per fresh install/first entrance
  • Reads Android install referrer — When available, performs deterministic matching using the clickId
  • Builds probabilistic fingerprint — If no referrer is found, collects device model, OS version, screen metrics, locale, timezone, user agent, timestamp, and optional clipboard value
  • Posts to match endpoint — Sends fingerprint to POST /api/link/match-link
  • Updates context state — Provides result via useDetourContext()

The provider performs network I/O and requires valid API_KEY and appID. If these are missing or invalid, matching will fail.

Key runtime guarantees

  • Single-run: The SDK is designed to attempt matching only once per install/first-open; it will not call the API repeatedly on every app open.
  • First-open semantics: The provider checks persisted state (AsyncStorage) to determine whether the device has already been processed; this avoids duplicate attribution attempts.
  • Clipboard: If shouldUseClipboard is true the provider checks the clipboard and includes pastedLink in the fingerprint. This behavior applies exclusively to iOS and may trigger the system's paste permission prompt.
  • Error handling: If the match API returns an error or network calls fail, provider will set deferredLinkProcessed = true and deferredLink = null so your app can continue. The SDK logs errors to the console for debugging.

Example

import { DetourProvider } from "@swmansion/react-native-detour";
import { NavigationContainer } from "@react-navigation/native";

function App() {
return (
<DetourProvider
config={{
API_KEY: "your-api-key",
appID: "your-app-id",
shouldUseClipboard: true,
}}
>
<NavigationContainer>{/* Your app navigation */}</NavigationContainer>
</DetourProvider>
);
}

useDetourContext()

Signature

export function useDetourContext(): DetourContextType;

Returns

DetourContextType object with the following properties:

PropertyTypeDescription
deferredLinkProcessedbooleantrue when the SDK has finished the deferred-link and universal/app link check (either success or failure). While false, your app should wait if you need to route the user based on a link.
deferredLinkstring | URL | nullThe raw link returned by the platform if matched. Can be a full URL string (e.g., https://yourorg.godetour.link/app-hash/promo) or a URL object. It can be deferred link, universal/app link or uri-scheme deep link.
Returns null if no match was found or an error occurred.
routestring | nullA normalized path extracted from the deferred link, universal/app link or uri-scheme deep link. Examples: "/promo/123?utm=1" (path with query string) or null if nothing matched.

Example

import { useDetourContext } from "@swmansion/react-native-detour";
import { useEffect } from "react";
import { useNavigation } from "@react-navigation/native";

function HomeScreen() {
const { deferredLinkProcessed, deferredLink, route } = useDetourContext();
const navigation = useNavigation();

useEffect(() => {
if (deferredLinkProcessed && route) {
// Navigate based on the deferred link route
console.log("Deferred link detected:", deferredLink);
console.log("Route:", route);

// Example: navigate to a specific screen
if (route.startsWith("/promo")) {
navigation.navigate("Promo", { url: deferredLink });
}
}
}, [deferredLinkProcessed, route, deferredLink, navigation]);

if (!deferredLinkProcessed) {
return <LoadingScreen />;
}

return <YourHomeScreen />;
}

Types

Config

export type Config = {
/**
* Your application ID from the Detour dashboard.
*/
appID: string;

/**
* Your API key from the Detour dashboard.
*/
API_KEY: string;

/**
* Optional (only for iOS): A flag to determine if the provider should check the clipboard for a deferred link.
* When true, it displays permission alert to user.
* Defaults to true if not provided.
*/
shouldUseClipboard?: boolean;

/**
* Optional: A custom storage adapter. Defaults to AsyncStorage if not provided.
*/
storage?: DetourStorage;
};

DetourContextType

export type DetourContextType = {
/**
* Boolean indicating if the deferred link or Universal/App Link has been processed.
* This is useful for conditionally rendering UI components.
*/
deferredLinkProcessed: boolean;

/**
* The deferred link or Universal/App Link. This can be a string or a URL object, or null if no link was found.
*/
deferredLink: string | URL | null;

/**
* The detected route based on the deferred link or Universal/App Link, or null if no route was detected.
*/
route: string | null;
};

DetourStorage

Your storage adapter should implement the following methods:

export interface DetourStorage {
getItem(key: string): Promise<string | null> | string | null;
setItem(key: string, value: string): Promise<void> | void;
removeItem?(key: string): Promise<void> | void;
}