Deep Linking Strategy
The Three Tiers of Mobile Linking
Deep linking has three distinct tiers of capability, and conflating them is the most common planning mistake. A basic deep link (myapp://product/123) opens a specific screen only if the app is already installed; it fails silently or falls to a browser otherwise. A universal/app link (iOS Universal Links, Android App Links) uses https:// URLs validated against a domain you control, so the same link opens the app if installed or the website if not — no fallback logic needed because it's a real web URL. A deferred deep link goes further: it survives an install, so a user who taps a link without the app routes through the store, installs, and still lands on the originally intended screen on first open.
Domain Verification: Universal Links and App Links
Universal Links require a /.well-known/apple-app-site-association (AASA) file hosted at your domain root, unencrypted and served over HTTPS with no redirects, declaring which app ID owns which URL paths. Android App Links require an equivalent /.well-known/assetlinks.json. iOS validates this file at app install time and caches it — meaning changes to your AASA file do not take effect for existing installs until the OS re-fetches it, which happens on app updates or periodically, not instantly. This caching behavior routinely causes 'why isn't my new deep link path working' confusion during rollout.
{
"applinks": {
"apps": [],
"details": [
{
"appID": "ABCDE12345.com.yourcompany.app",
"paths": [
"/product/*",
"/campaign/*",
"NOT /admin/*"
]
}
]
}
}Universal Links Degrade Silently
Deferred Linking Needs an MMP (Usually)
True deferred deep linking — surviving the App Store round-trip — isn't something Apple's or Google's native linking frameworks support on their own; iOS Universal Links simply don't fire at all during an app-not-installed flow. This is why Branch, AppsFlyer OneLink, and Adjust all exist as the practical layer: they intercept the click on a web domain they control, log the intended destination, and after SDK-detected first-open, hand the destination back to your app via their SDK rather than the OS's native link-handling APIs.
Designing the Link Taxonomy Before You Need It
A deep link strategy fails in practice far more often from poor URL structure than from technical misconfiguration. Decide upfront:
- Route structure: mirror your app's internal navigation hierarchy (/category/:id/product/:id) so links stay predictable as the catalog grows.
- Campaign parameters: separate the *destination* (what screen) from the *attribution context* (which campaign/channel sent the user) — don't overload a single path segment to carry both.
- Fallback behavior per channel: a link in a push notification can assume the app is installed and skip web fallback logic entirely; a link in a paid social ad must handle both installed and not-installed cases gracefully.
// Example: handling an incoming deep link inside a React Native app
import { Linking } from 'react-native';
import { useNavigation } from '@react-navigation/native';
function useDeepLinkRouter() {
const navigation = useNavigation();
useEffect(() => {
const handleUrl = ({ url }: { url: string }) => {
const parsed = new URL(url);
const segments = parsed.pathname.split('/').filter(Boolean);
if (segments[0] === 'product' && segments[1]) {
navigation.navigate('ProductDetail', { productId: segments[1] });
} else if (segments[0] === 'category' && segments[1]) {
navigation.navigate('Category', { categoryId: segments[1] });
}
// Always have a default fallback to the home screen
// for unrecognized paths rather than crashing or stalling.
};
const subscription = Linking.addEventListener('url', handleUrl);
return () => subscription.remove();
}, [navigation]);
}QR Codes Are Deep Links With Extra Friction
Measuring Link Performance
Beyond click and install counts, the metric that actually indicates whether your deep link strategy is working is post-click-to-destination conversion — whether users who tap a link reach and engage with the intended screen, versus landing on a generic home screen due to a fallback failure. This requires instrumenting a confirmation event (e.g., deep_link_resolved with the matched route) that you can compare against total link clicks reported by your MMP.
What's Next?
iOS has steadily tightened what identifiers and signals a deep link or attribution SDK can rely on, and that same privacy pressure is what produced Apple's constrained alternative measurement framework worth understanding next.
I build these systems professionally.
Whether it's a RAG pipeline, analytics migration, or AI workflow — let's talk.