Deep linking in React Native has three layers: the OS-level link registration (schemes + Universal/App Links), the in-app routing (React Navigation), and — if you run campaigns — deferred deep linking for new installs. Here's how to wire all three, on both platforms, in 2026.
1. Register your links with the OS
iOS — Universal Links: add the Associated Domains capability in Xcode (applinks:go.yourapp.com) and host an apple-app-site-association file on that domain. Keep a custom scheme (yourapp://) as a secondary path.
Android — App Links: add an autoVerify intent filter to your launch Activity and host an assetlinks.json with your package name and signing SHA-256.
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" android:host="go.yourapp.com" />
</intent-filter>
2. Handle links in JavaScript
React Native's Linking API gives you both the cold-start URL and live events:
import { Linking } from 'react-native';
// App opened from a link (cold start)
const initialUrl = await Linking.getInitialURL();
// App already open
const sub = Linking.addEventListener('url', ({ url }) => route(url));
3. Let React Navigation route the path
Give the navigator a linking config so paths map to screens automatically:
const linking = {
prefixes: ['https://go.yourapp.com', 'yourapp://'],
config: { screens: { Show: 'show/tv/:id', Profile: 'u/:handle' } },
};
<NavigationContainer linking={linking}>…</NavigationContainer>
Now https://go.yourapp.com/show/tv/42 opens the Show screen with id=42.
4. Test it
- Simulators:
npx uri-scheme open "https://go.yourapp.com/show/tv/42" --ios(and--android). - Android device:
adb shell am start -a android.intent.action.VIEW -d "https://go.yourapp.com/show/tv/42". - Verify App Links with Google's Statement List Tester; reinstall so Android re-runs verification.
5. Deferred deep linking (new installs) — without a heavy SDK
For users who tap a link before installing, call a resolve endpoint once on first launch to recover where they were headed. With lynkily that's a single REST request — no MMP SDK to embed:
const r = await fetch(
'https://lynkily.com/api/v1/attribution/init',
{ method: 'POST', headers: {'Content-Type':'application/json'},
body: JSON.stringify({ app: 'yourapp', platform: 'ios' }) }
);
const { deep_link } = await r.json(); // { path: 'show/tv/42' }
if (deep_link) navigate(deep_link.path);
Skip the association-file hassle
lynkily Deep Links hosts your AASA and assetlinks.json for you, builds the app → store → web fallback into every link, and exposes the resolve + events API you called above — so the RN side stays this small. Also see our Expo deep-linking guide. Background: Universal Links vs App Links and deferred deep linking.