Testing & Troubleshooting
Testing deferred linking has platform constraints. The complete deferred flow requires the store redirect chain, that is the App Store or Google Play.
Testing iOS
Section titled “Testing iOS”If your app is not yet released:
- Remove any existing install from the device so the next open counts as a first launch.
- Open a Detour link in a mobile browser.
- Expect the App Store redirect to fail. With no public listing yet, the store has no listing to open, which does not affect the test.
- Install your development build.
- Launch the app and confirm the link resolves within the matching window (currently 15 minutes).
Testing Android
Section titled “Testing Android”For non-production builds, the install referrer often does not work in store test tracks, so deterministic matching can be unavailable. You can still verify the probabilistic flow:
- Uninstall the app from the device.
- Open a Detour link in a mobile browser.
- Expect the Play Store redirect to fail when the production listing is unavailable.
- Install your development build.
- Launch the app and confirm the link resolves within the matching window (currently 15 minutes).
For local install referrer testing workarounds, see How to test the Play Store Install Referrer API.
Testing Android App Links
Section titled “Testing Android App Links”Whether an installed app opens a Detour link depends on the Dashboard SHA-256 matching the key that signed the build on your device:
| Installation method | SHA-256 to configure | Where to find it |
|---|---|---|
| Google Play, any track | Play App Signing key | Play Console → Protected with Play → Manage Play app signing → App signing key certificate |
eas build, any profile, including development | Keystore in your EAS account | eas credentials -p android → profile → Keystore → SHA256 Fingerprint |
npx expo run:android / npx react-native run-android | Project’s android/app/debug.keystore | keytool -list -v -keystore android/app/debug.keystore -storepass android, or ./gradlew signingReport |
To check any build directly: apksigner verify --print-certs app-debug.apk. The complete procedure is described in Finding your Android SHA-256 fingerprint.
Common issues
Section titled “Common issues”- No match found (
404)- click is older than matching window
- click was not recorded in Dashboard logs
- for deterministic Android flow: missing
click_idin referrer
429 Too Many Requests- add retry/backoff and avoid heavy testing with one key across many devices
- iOS clipboard prompt not appearing
- check
shouldUseClipboard: true - verify copy-link flow is enabled in Dashboard
- check
- iOS Universal Link opens the browser instead of the app during development
- before your domain and App Store listing have fully propagated, iOS resolves the
apple-app-site-associationfile through Apple’s CDN, which may not have it yet - append
?mode=developerto the matching entry in your iOSassociatedDomains(e.g.applinks:yourorg.godetour.link?mode=developer) so the device fetches the association file directly from your server, bypassing the CDN - this also requires enabling Developer Mode on the test device (Settings → Privacy & Security → Developer Mode). Remove the
?mode=developersuffix before shipping
- before your domain and App Store listing have fully propagated, iOS resolves the
- Universal/App link not delivered,
[Detour:CLICK_LIMIT_ERROR]in logs- your app exceeded its click limit for the current period. Check your plan’s limits in Billing & Payments
- the dedicated
CLICK_LIMIT_ERRORis emitted only for Universal/App links. Deferred and short links share the same plan limits, but over the limit they fail to resolve (they returnnull, with no dedicated error), and custom scheme links are not limit-checked - a temporary network/backend error never blocks a link (the check fails open)
- Link processed twice
- confirm you call
clearLink()after navigation - confirm exactly one
DetourProviderinstance is mounted
- confirm you call
- Link is not processed on Expo Web
- web runtime is intentionally unsupported
- provider on web returns a no-op context and skips SDK initialization
Bare React Native CLI build issues
Section titled “Bare React Native CLI build issues”These apply only to bare React Native CLI projects that added Expo Modules with install-expo-modules (see Bare React Native projects). They are bundler/environment issues, not SDK bugs. The SDK itself is plain JavaScript.
| Symptom | Cause | Fix |
|---|---|---|
iOS: TypeError: Cannot read property '…' of undefined at startup | Expo Modules native code is not linked | Run npx install-expo-modules@latest, then reinstall CocoaPods |
Android release: Serializer did not return expected format … Unexpected token 'v', "var __BUND"... is not valid JSON | metro.config.js uses @react-native/metro-config while the build bundles with Expo CLI (export:embed) | Make metro.config.js extend expo/metro-config. See Expo Modules setup |
The NODE_ENV environment variable is required but was not specified | export:embed ran without an environment set | Set NODE_ENV=production for the release build |
cliFile … is not a file … it was a directory | @expo/cli is not hoisted to the top-level node_modules | Install it at the project root (npm install @expo/cli@<version>) or do a clean reinstall |
Bundling fails because node is not found | node is not on the PATH of the Gradle process (common with nvm) | Make sure node is on PATH for the build and restart the Gradle daemon (./gradlew --stop) |
For integration patterns that are easy to test end-to-end, use Examples.