skills/detour/detour-onboarding/SKILL.md
Complete onboarding guide for developers who are new to Detour, the open-source deferred deep linking SDK by Software Mansion. Use this skill whenever a user asks what Detour is, how to get started with Detour, how to set up deep linking with Detour, how to install the Detour SDK, how to configure the Detour dashboard, or how deferred deep linking works. Also use it when the user has no prior deep linking setup and wants to add deep links to their app. Covers everything from zero to production: account setup, dashboard configuration, Universal Links and App Links, platform SDK integration for React Native, iOS, Android, and Flutter, analytics, and architecture.
npx skillsauth add software-mansion-labs/react-native-skills detour-onboardingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You are a friendly onboarding guide helping a developer understand and set up Detour from scratch.
Detour is an open-source deferred deep linking SDK by Software Mansion. It lets you send users to specific in-app content even when the app is not installed yet — the link context survives the App Store / Play Store installation and is retrieved on first app open.
Walk the user through this mental model:
https://yourorg.godetour.link/APP_HASH/articles/2)Beyond deferred links, Detour also handles Universal Links (iOS) and App Links (Android) — direct links that open the app immediately when the app is already installed.
The canonical Detour link looks like:
https://YOUR_ORG.godetour.link/APP_HASH/your/path?param=value
Example: https://matitest.godetour.link/VnAqasAabE/articles/2
The APP_HASH is the unique identifier generated by the dashboard for your app. The path and query string after it are the in-app destination.
Short links are separate and optional. They are campaign-specific aliases created in the Link Settings tab. Do not confuse them with the default link format — the default link is what you get immediately after creating an app, no extra steps needed.
Before diving into any platform-specific steps, ask the user two questions together:
Which platform(s) are you building for?
Do they already have a Detour account and app configured on the dashboard?
If they have an account, skip to Phase 2. Otherwise start at Phase 1.
Do this once, regardless of platform.
https://YOURORG.godetour.linkThe dashboard auto-generates:
https://YOURORG.godetour.link/APP_HASH/...)Link Settings tab:
App Configuration tab:
apple-app-site-association and assetlinks.json filesAPI Configuration tab:
After Phase 1, the user should have their subdomain, App ID, Publishable API Key, and App Hash ready.
Universal Links (iOS) and App Links (Android) let Detour links open the app directly when already installed, bypassing the browser. Detour hosts the required verification files automatically.
The only change needed is registering the Detour domain inside the app. Load the relevant reference file:
references/react-native.md — "Universal / App Links" sectionreferences/ios.md — "Universal Links" sectionreferences/android.md — "App Links" sectionreferences/flutter.md — "Universal / App Links" sectionLoad the reference file for the user's platform:
references/react-native.mdreferences/ios.mdreferences/android.mdreferences/flutter.mdlinkProcessingMode controls which link sources the SDK handles:
| Mode | Deferred | Universal/App Links | Custom scheme |
|------|:-:|:-:|:-:|
| all (default) | yes | yes | yes |
| web-only | yes | yes | no |
| deferred-only | yes | no | no |
Start with all unless there is a specific reason not to.
The link result object — all platforms return:
route — full path and query string ready for navigation (e.g. /articles/2?ref=campaign)pathname — path without query stringparams — parsed query parameters as a key/value mapurl — original full URLtype — deferred, verified (Universal/App Link), or schemeAlways call clearLink() or consume the intent after navigating to prevent re-navigation on app resume.
Detour automatically tracks (no code needed):
Dashboard views: Overview (trends and retention), Links (day-by-day per campaign), Events (custom SDK events).
Use DetourAnalytics.logEvent with values from the DetourEventNames / DetourEventName enum. Do not invent custom event name strings — only enum values are accepted for standard events:
// Correct — enum value
DetourAnalytics.logEvent(DetourEventNames.Purchase, { revenue: 29.99 })
// Wrong — "article_opened" does not exist in the enum
DetourAnalytics.logEvent("article_opened", {})
For events that have no enum equivalent, use logRetention with a descriptive string:
DetourAnalytics.logRetention("article_opened")
Platform-specific syntax is in the reference files. Retention tracks up to 30 days from first logRetention call.
Explain when the user asks "how does it know who installed?" or wants to understand reliability.
When the Play Store passes an install referrer with the exact click_id, Detour looks it up directly — exact match, very reliable.
When there is no click_id, Detour scores the install against recent unmatched clicks:
| Signal | Points | |--------|--------| | IP address exact match | 500 | | Device model + OS version | 450 | | User-agent device signature | 350 | | iOS pasteboard token | 350 | | Timezone | 200 | | Screen dimensions | 200 | | Language | 100 |
Default threshold: 850 points (configurable 700-1200). Time window: 15 minutes (configurable 5-180 min).
click_id, forcing probabilistic path on Androidhttps://YOUR_ORG.godetour.link/APP_HASH/your/pathlink object is populated with the expected routeImportant: Each deferred link test requires the app to be uninstalled first. Clicking the link while the app is installed resolves it as a Universal/App Link, not deferred. Also, each deferred test needs a fresh link — the same link won't trigger deferred resolution a second time on the same device.
Do not use short links for initial testing — test with the default https://ORG.godetour.link/APP_HASH/path format first.
Click the link while the app is installed — it should open directly without going through a browser.
For Android 12+: see the testing section in references/android.md — debug APKs need manual adb enabling.
Always check your project's README or package.json scripts for the correct run command. Do not assume npx react-native run-android — many projects use npm run android or a custom script.
YOUR_API_KEY, YOUR_APP_ID, YOUR_ORG — never ask for real credentialsDetourEventNames/DetourEventName enum values in logEvent — never invent event name stringsdevelopment
Use when the user mentions migrating deep links, switching away from Branch or AppsFlyer, replacing their deep linking SDK, setting up Detour deep linking for the first time, or asks how Branch/AppsFlyer concepts map to Detour. Covers the complete migration end to end - Detour Dashboard configuration, Universal Links and App Links setup, SDK swap with code examples, and analytics migration. Works across Android, iOS, React Native, and Flutter.
tools
React Native / Expo SDK for Fishjam — video/audio streaming on iOS and Android. Use when writing a React Native or Expo app that calls Fishjam, configures the Fishjam Expo plugin, sets up permissions, runs background streaming, integrates CallKit, or renders RTCView. Trigger on: '@fishjam-cloud/react-native-client', 'fishjam expo plugin', 'FishjamProvider mobile', 'useCameraPermissions', 'useMicrophonePermissions', 'useForegroundService', 'useCallKit', 'useCallKitEvent', 'useCallKitService', 'RTCView', 'RTCPIPView', 'ScreenCapturePickerView', 'startPIP', 'stopPIP', 'AudioDeviceType', 'useAudioOutput', '@fishjam-cloud/react-native-webrtc', 'fishjam react native', 'expo fishjam', 'fishjam ios', 'fishjam android', 'broadcast extension'. Re-exports @fishjam-cloud/react-client hooks plus mobile-only: permissions, foreground service, iOS broadcast extension, audio routing, CallKit, Expo config plugin.
tools
Browser-only React SDK for Fishjam — joining rooms, capturing camera/microphone/screen, displaying peers, and acting as a livestream streamer or viewer in a React web app. Use whenever the user is writing a React app in a browser that calls Fishjam APIs, sets up FishjamProvider, or uses any Fishjam React hook. Trigger on: '@fishjam-cloud/react-client', 'FishjamProvider', 'useConnection', 'useCamera', 'useMicrophone', 'useScreenShare', 'usePeers', 'useDataChannel', 'useVAD', 'useLivestreamStreamer', 'useLivestreamViewer', 'useCustomSource', 'useInitializeDevices', 'useUpdatePeerMetadata', 'useSandbox', 'PeerWithTracks', 'joinRoom', 'peerToken', 'fishjamId', 'fishjam react', '@fishjam-cloud/ts-client', 'FishjamClient ts-client'. Covers the provider, the full hook catalog, simulcast configuration, custom sources, data channels, VAD, livestream WHEP playback, device persistence, and reconnection. Briefly notes when to drop down to @fishjam-cloud/ts-client for non-React or worker contexts.
tools
Python server SDK for Fishjam — backends that create rooms, mint peer tokens, receive server notifications, and run voice agents. Use when writing a Python backend (FastAPI, Flask, Starlette, aiohttp) that talks to Fishjam, decorates a notification handler, decodes a Fishjam webhook, or builds an AI voice agent in Python. Trigger on: 'fishjam-server-sdk', 'pip install fishjam-server-sdk', 'from fishjam import', 'fishjam.FishjamClient', 'FishjamNotifier', 'on_server_notification', 'receive_binary', 'fishjam Agent', 'AgentSession', 'PeerOptions', 'RoomOptions', 'AgentOptions', 'AgentOutputOptions', 'OutgoingAudioTrackOptions', 'create_room', 'create_peer', 'create_agent', 'create_vapi_agent', 'create_livestream_streamer_token', 'create_moq_token', 'subscribe_peer', 'fastapi fishjam', 'flask fishjam', 'fishjam python', 'gemini fishjam python'. Python 3.10+. The REST client is synchronous; notifier and agent are async.