Diagnosing Deep Link Failures in React Navigation v6
Step‑by‑step checklist to identify why React Navigation v6 ignores incoming deep links and how to fix each common cause.
22 Mar 2026, 04:38 UTC

Recognizable condition
When you tap a link like myapp://settings (or click a universal link) the app opens but stays on the initial screen instead of navigating to the Settings screen.
Cause and diagnostic table
| Possible cause | What you observe |
|---|---|
| Missing or incorrect linking configuration in NavigationContainer | Link is ignored; console may show warning “Could not resolve link”. |
| Target screen not registered in the navigator | Link falls back to the first route; no warning about missing screen. |
| URI scheme mismatch between link and native project config | Link does not launch the app at all (or opens a browser fallback). |
| NavigationContainer unmounted when link arrives | App opens but link event is lost; you see the initial screen and no navigation. |
Ordered checks
-
Verify linking prop
Check that the
linkingobject passed to<NavigationContainer>defines the correctprefixesand aconfigthat maps each path to a screen name.import { createLinking } from '@react-navigation/native'; const linking = { prefixes: ['myapp://'], config: { screens: { Settings: 'settings', Profile: 'profile/:id', }, }, }; function App() { return ( {/* navigators */} ); }If the prefixes do not include the scheme used in the incoming link (e.g.,
myapp://), the linker will ignore it. -
Confirm screen registration
Ensure every screen referenced in
linking.config.screensis actually present in the navigator’s route list.Example: a stack navigator must have a
Screen name="Settings" component={SettingsScreen} />entry. -
Check native URI scheme configuration
For Android, open
android/app/src/main/AndroidManifest.xmland verify an intent‑filter with the same scheme and host:<intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="myapp" /> </intent-filter>For iOS, open
Info.plistand confirm a URL Types entry withURL identifierandURL Schemescontainingmyapp. -
Ensure NavigationContainer is mounted when the link is processed
Avoid rendering the container conditionally before the app finishes launching. A common pattern is to wrap the whole app in
NavigationContainerunconditionally:export default function App() { return ( ); }If you need to wait for auth state, keep the container mounted and change the inner navigator instead.
Fixes tied to findings
- If step 1 reveals a missing prefix, add the scheme to
prefixesand restart the dev server. - If step 2 shows an undefined screen, add the missing
Screencomponent to the navigator or correct the name in the linking config. - If step 3 finds a scheme mismatch, edit the native project files (AndroidManifest.xml or Info.plist) to match the scheme used in
linking.prefixesand rebuild the native binaries. - If step 4 shows the container unmounted, move
NavigationContainerto the top level of the app tree.
Escalation criteria
Proceed to deeper investigation when:
- All checks pass but the link still does not trigger navigation.
- You see linking warnings that reference “unknown source” after verifying config.
- The app launches but navigation state does not update (check with
navigation.getState()or React DevTools). - You are using Expo managed workflow and suspect missing
schemeinapp.json; runexpo prebuildto regenerate native files.
At this point, examine the native side:
- Run
adb logcat(Android) or device console (iOS) and look for activity start intents or URL handling logs. - Confirm that the intent‑filter or URL Types are correctly placed inside the
<application>tag. - For Expo, verify
schemeunderiosandandroidinapp.jsonand runexpo run:androidorexpo run:iosto see the generated native configuration.
Limitations and practical verification
This guide assumes React Navigation v6 and a functional deep‑link URI (e.g., myapp://settings). It does not cover universal links (Apple App Links) or Android App Links, which require additional domain association files.
To verify a fix, repeat the link test:
- Android:
adb shell am start -W -a android.intent.action.VIEW -d myapp://settings - iOS: open the URL from Safari, Notes, or run
xcrun simctl openurl booted myapp://settingson a simulator. - Watch the screen change to the target route and optionally log
navigation.getState()to confirm the state includes the expected screen name.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.