When the app is cold-launched from a deep link — the user taps a push notification or a universal link while the app is killed — React Navigation relies on the linking config to seed the initial route. If only warm handling exists, cold launches drop the user on Home with the deep-link payload lost; if only cold handling exists, links received while the app is backgrounded do nothing. Either gap silently breaks re-engagement and violates App Store expectations for universal links.
Medium because one of the two deep-link paths works, but half of incoming links fail depending on app state.
React Navigation handles both cold and warm deep links automatically when linking is passed to NavigationContainer, but test both paths. Add an explicit handler only if you need custom routing logic:
import * as Linking from 'expo-linking'
useEffect(() => {
const sub = Linking.addEventListener('url', ({ url }) => {
// custom warm-link logic (analytics, auth gate)
})
return () => sub.remove()
}, [])
Verify with xcrun simctl openurl booted myapp://product/123 from cold and warm states.
ID: mobile-navigation-linking.navigation-ux.cold-warm-deeplinks
Severity: medium
What to look for: Check the deep link handling. "Cold-start" means the app is launched from a deep link (not already running). "Warm" means a deep link is received while the app is open. Examine the linking config for a fallback handler. Check whether useDeepLinkURL or addEventListener('url', ...) is used for warm deep links.
Pass criteria: Count all deep link handling pathways (cold-start via linking config, warm via URL event listener). At least 2 pathways must exist — 1 for cold-start (linking config) and 1 for warm deep links (URL listener or equivalent). Both cases must navigate to the correct screen and pass parameters correctly.
Fail criteria: Deep links only work when the app is already open, or only work on fresh launch. Warm deep links do not trigger navigation.
Skip (N/A) when: The app does not receive deep links (no linking config defined).
Detail on fail: "Deep links only open the correct screen when the app is already running — cold-start launches go to Home" or "App doesn't respond to deep links received while open"
Remediation: React Navigation handles cold-start deep links via the linking config automatically. For warm deep links (while app is running), add a URL listener:
const [initialRoute, setInitialRoute] = useState(null)
useEffect(() => {
const unsubscribe = navigation.addListener('state', ({ data }) => {
// Or use: const link = linking.getStateFromPath(url)
})
// For deep links received while app is open
const unsubscribeLinking = linking.onStateChange?.(() => {}) || (() => {})
return () => {
unsubscribe()
unsubscribeLinking()
}
}, [])
Most deep link handling is automatic with React Navigation if your linking config is correct. Test on both cold-start and warm scenarios.