How Branch deep linking routes a mobile user to the right screen, even across an app install, and the universal-link and privacy gotchas that decide whether it works.
Key findings
Deep linking sends a user to a specific screen instead of the app's home; done well it is invisible, done badly it leaks growth by dropping every new install onto a generic launch screen.
Universal Links (iOS) and App Links (Android) only work when the app is already installed. They cannot carry a destination through an install, which is the gap Branch exists to fill.
Deferred deep linking is the headline feature: tap a link without the app, install it, and still land on the intended screen on first launch. One Branch link also works across iOS, Android, and desktop web.
The reliability of deferred matching has dropped since iOS 14 and App Tracking Transparency, because it leaned on probabilistic device fingerprinting; deterministic paths still work, probabilistic install matching is now best-effort.
The two things that most often break a setup are a misconfigured apple-app-site-association file and an over-reliance on clipboard or fingerprint matching that privacy changes have weakened.
A link is a promise: tap this, get that. On the web the promise is easy to keep. On mobile it breaks constantly, because the path from a tapped link to the right screen runs through app stores, cold installs, and two operating systems that each handle links differently. This is a practitioner's look at how Branch deep linking keeps that promise, how it works across an install, and the gotchas that decide whether it holds up in production.
What problem does mobile deep linking actually solve?
Mobile deep linking solves the gap between a link a user taps and the specific screen they expected to reach. On the web, a URL points at a page and the browser loads it. On mobile, the same tap has to decide: is the app installed? If yes, open it to the right screen; if no, send the user to the store, and then, after they install, still deliver them to that screen. Every step in that chain is a place to lose someone.
The cost of getting this wrong is silent. A user taps a shared product link, does not have the app, installs it from the store, and lands on a generic home screen with no memory of what they came for. They rarely retype their way back. Marketing spends to drive that install and then wastes it at the last step. Deep linking, done properly, closes that leak so the destination survives the whole journey, including the install.
There is a second job layered on the first: attribution. Because a deep-link platform sits in the middle of every link tap and install, it can also report where installs came from, which campaign or channel drove them, and what those users did next. That makes deep linking as much a growth-measurement tool as a routing one.
What does Branch add over native Universal Links and App Links?
Branch adds the one thing the operating systems cannot do on their own: carry a destination through an app install, plus attribution and a single cross-platform link. Modern mobile links come in two OS-native forms. On iOS, a Universal Link is a normal https URL that opens the app directly, with no browser bounce, when the app is installed. On Android, an App Link does the same. Both are secure and deterministic, and both share one hard limit: they only work when the app is already on the device.
That limit is exactly where growth leaks. A first-time user who taps a link has no app to open, so the OS-native link has nothing to route to. Branch fills that gap with deferred deep linking: it remembers the intended destination, sends the user to install, and hands the destination to the app on first launch. According to Branch's own documentation, this deferred behavior across the install boundary is the core of what the platform provides beyond native links.
The rest is convenience and measurement. One Branch link resolves correctly on iOS, Android, and desktop web instead of maintaining three link schemes. And because Branch brokers the click and the install, it can attribute installs to campaigns. If your app never needs to route a fresh install or measure where users come from, native links are enough. Most consumer and fintech apps need both. For teams weighing this against a broader build, our mobile app development work treats deep linking as part of the growth surface, not an afterthought.
How does a Branch deep link resolve, step by step?
A Branch link resolves by first asking whether the app is installed, then taking one of two paths: open-and-route, or store-install-then-route. When a user taps a Branch link, Branch's link service inspects the context and decides the best route for that platform and state.
One link, three outcomes: open the installed app, defer through an install, or fall back to web.
If the app is installed, a Universal Link or App Link opens it directly and the app reads the link parameters to route to the target screen. If the app is not installed, the user is sent to the store; after install, the Branch SDK on first launch retrieves the original parameters and routes to the same screen, so the destination survives. If the context cannot support an app at all, such as a desktop browser or an in-app webview that blocks the handoff, the link falls back to a web page. The app never trusts the client alone to decide the route: the parameters that drive it come back from Branch, which keeps a link tap and its eventual install tied together.
What does the app-side integration look like?
The app-side integration is small: initialize the SDK once, then subscribe to the deep-link parameters it delivers on open and on first launch. The SDK abstracts the difference between an already-installed open and a deferred first launch, so the app handles both through one callback.
// React Native (Expo bare / RN). One subscription handles both an// already-installed open and a deferred first launch after install.import branch, { BranchParams } from 'react-native-branch';import { router } from 'expo-router';type DeepLinkParams = BranchParams & { screen?: string; productId?: string;};export function initDeepLinking(): () => void { const unsubscribe = branch.subscribe(({ error, params }) => { if (error || !params) return; // fail-soft: fall through to the default route if (!params['+clicked_branch_link']) return; // not a Branch link, ignore const { screen, productId } = params as DeepLinkParams; if (screen === 'product' && productId) { router.push(`/product/${productId}`); // route to the intended screen } }); return unsubscribe; // detach on teardown}
Two things matter here. The callback fires for both cases, so a first launch after install and a normal open share one routing path. And it is written to fail soft: an error, missing params, or a non-Branch link simply falls through to the app's default screen rather than crashing or trapping the user. That resilience matters because, as the next sections show, the match is not always available.
Why is deferred deep linking less reliable than it used to be?
Deferred deep linking is less reliable now because the technique it once leaned on, probabilistic device fingerprinting, has been deliberately degraded by platform privacy changes. To connect a link tapped in a browser to an install that happens minutes later in a separate app, the platform historically compared device signals (IP, model, OS) to guess that the two events were the same person. That guess was never perfect, and Apple's App Tracking Transparency plus broader anti-fingerprinting moves have made it markedly weaker.
What still works reliably is deterministic matching: a real Universal Link opening an installed app, or a Branch-hosted flow that round-trips a genuine identifier. What has become best-effort is probabilistic install matching for a cold install. According to Apple's Universal Links documentation, the deterministic path (the app claiming its domain) is the supported, robust mechanism; anything that infers identity across an install now sits on shakier ground.
The practical takeaway is to design for a miss. A deferred match that fails should drop the user onto a sensible default, a relevant category or an onboarding screen, not a blank or broken view. Treating the match as a bonus rather than a guarantee keeps the experience solid even as accuracy drifts. This is the kind of trade-off our front-end development practice bakes into the flow from the start.
What are the risks and gotchas?
The failure modes cluster in a few predictable places, and knowing them up front saves a painful debugging cycle after launch.
The apple-app-site-association file is fragile. Universal Links depend on a file served over https at the domain root, with the correct content type, no redirects, and app IDs that match the build. iOS caches it aggressively, so fixes can take hours or a reinstall to take effect. A single wrong field silently downgrades every Universal Link to a browser bounce. Android's assetlinks.json has the same class of problem.
Entry points bypass the link. Long-pressing a link, pasting it into a browser bar, or opening it from inside certain apps (some chat and social webviews) can skip the Universal Link and open the browser instead. The only way to trust a setup is a test matrix across real entry points, not a single tap from Notes.
Clipboard and fingerprint matching carry privacy cost. Recovering a deferred link on iOS can involve reading the clipboard, which since iOS 14 shows a visible paste banner and reads as intrusive. Turning it off improves the privacy story but lowers deferred-match rates. This is a conscious trade-off, not a default to accept blindly.
Attribution data is tracking data. A deep-link SDK that measures campaigns processes device and campaign identifiers, which brings GDPR and consent obligations. Gate non-essential collection behind consent and confirm the vendor's data-processing terms.
The SDK is a dependency with weight. It adds size, a native module, and a moving vendor surface to keep updated as iOS and Android change. Budget for maintenance, not just the initial wire-up.
How does it behave across three real scenarios?
The design is easiest to understand through the three journeys it has to handle.
Scenario 1: the app is already installed
A user with the app taps a shared product link. The Universal Link opens the app directly, the SDK delivers the link parameters, and the app routes straight to the product screen. No browser flash, no store, no lost context. This is the clean deterministic path and it is the one that should work every time; if it does not, the apple-app-site-association or assetlinks.json configuration is the first suspect.
Scenario 2: the app is not installed yet
A first-time user taps the same link. Branch remembers the destination, sends them to the store, and they install. On first launch the SDK retrieves the original parameters and routes them to the same product screen, so the reason they tapped survives the install. When the deferred match succeeds, this is the feature that pays for the whole integration. When it misses, because of privacy limits, the app should still open to a relevant default rather than a blank home.
Deferred deep linking carries the destination across the one boundary native links cannot: the install.
Scenario 3: an unsupported or desktop context
The link is opened on a desktop browser, or inside a webview that blocks the app handoff. There is no app to route to, so the link falls back to a web page that mirrors the destination, ideally with a prompt to continue in the app. Designing this web fallback deliberately means a link shared into any channel still does something useful instead of dead-ending.
What would we do differently, or advise up front?
The highest-leverage decision is to lean on deterministic links and treat probabilistic matching as a bonus. Invest first in correct Universal Links and App Links, because that path is robust and privacy-durable; let deferred matching enhance the cold-install case rather than carry it. Build the web fallback as a real destination, not a placeholder, so no shared link ever dead-ends.
Beyond that: own the link domain rather than borrowing a shared one, since link-domain reputation affects deliverability and trust. Ship a documented test matrix that covers installed and uninstalled states across both platforms and multiple entry points, and re-run it on every OS update. Decide the clipboard and consent trade-offs explicitly and write them down. None of these are exotic; they are the difference between deep linking that quietly works and deep linking that quietly leaks.
Frequently asked questions
What is the difference between a deep link, a universal link, and a deferred deep link?
A deep link is any URL that opens a specific screen inside an app rather than its home screen. A universal link (iOS) or App Link (Android) is the modern, secure form that opens the app directly from a normal https URL with no browser bounce. A deferred deep link carries that destination through an app install: the user taps a link without the app, installs it, and lands on the intended screen on first launch. Branch's main job is the deferred case, which the OS does not handle on its own.
Do you still need Branch if universal links and App Links already exist?
Universal links and App Links only work when the app is already installed; they cannot carry a destination through an install. Branch adds deferred deep linking, one link that behaves correctly across iOS, Android, and web, and attribution data about where installs came from. If you never need to route a brand-new install or measure campaigns, native links alone are enough; most growth-focused apps need more.
Why does iOS sometimes show a paste or clipboard prompt on first launch?
Deferred deep linking on a fresh install has no shared identifier between the browser and the app, so some SDKs read the clipboard to recover the link the user tapped. Since iOS 14 that triggers a visible paste notification, which can feel intrusive. Branch offers configuration to avoid or reduce clipboard use, but the trade-off is lower deferred-match accuracy. It is worth deciding this consciously rather than shipping the default.
How reliable is deferred deep linking after recent privacy changes?
Less reliable than it used to be. Deferred matching leaned on probabilistic device fingerprinting, which Apple's App Tracking Transparency and broader privacy changes have degraded. Deterministic matching (a real universal link into an installed app, or a Branch-hosted link that round-trips) still works well; probabilistic install matching is now best treated as best-effort, not guaranteed. Design flows so a missed match degrades to a sensible default rather than a broken screen.
What breaks universal links most often?
The apple-app-site-association file. It must be served over https at the domain root with the correct content type, no redirects, and matching app IDs, and iOS caches it aggressively so changes are slow to take effect. Long-pressing a link, pasting it, or opening it from inside certain apps can also bypass the universal link and fall back to the browser. A test matrix across entry points is the only way to trust it.
Does deep linking require user consent under GDPR?
The routing itself does not, but the attribution and analytics Branch collects can, since it processes device and campaign identifiers. Treat the deep-link SDK like any other tracking dependency: gate non-essential data collection behind consent, document what is stored, and confirm the vendor's data-processing terms against your own compliance requirements before launch.
Deep linking is one of those systems that is invisible when it works and expensive when it does not. The durable version leans on deterministic Universal Links and App Links, uses Branch's deferred matching as an enhancement for cold installs, and always has a real web fallback behind it. Get those three right, keep the test matrix current, and a tapped link keeps its promise from any channel, on any device, installed or not. If you are weighing a deep-link build or untangling one that leaks, get in touch.
Your next project?
Whether it's an internal tool for your company or a highly available Software-as-a-Service - we help you to get your ideas off the ground!