Web-to-app handoff for a freemium funnel
Web-to-app handoff without the restart: pass onboarding state through the install so users resume mid-flow — the activation lift freemium funnels compound on.
Freemium products love the web for the top of the funnel — it's frictionless, indexable, and shareable. But the best experience lives in the app. The handoff between them is where activation quietly bleeds: the user does three steps on the web, installs, and the app makes them start over.
The context cliff
A browser cannot pass state to a freshly installed app. So the email captured, the plan selected, the workspace named — all of it evaporates at install unless you deliberately carry it across.
Pass onboarding state through the store
When the web flow hands off to install, encode the progress into the deferred link. On first open, the app reads it and drops the user back into the funnel where they left it.
{
"deepLinkPath": "/onboarding/step-3",
"customData": {
"email": "sam@example.com",
"plan": "pro-trial",
"workspace": "acme",
"step": 3
}
}Pick the right resume screen
- Resume at the next incomplete step — never replay steps they already finished.
- Pre-fill, don't pre-submit — let the user confirm carried data so it feels trustworthy.
- Have a clean fallback if the payload is missing, so a cold install still works.
What should you not pass through the link?
Anything you would not be comfortable seeing in a log. A link payload travels through a redirect, may be stored on the click record, and can be reconstructed by anyone who has the URL — so treat it as a hint about where the user was, not as a place to move sensitive state.
- Never pass credentials, tokens, or session identifiers. Pass a short-lived, single-use handoff reference the app exchanges server-side.
- Be careful with personal data. An email address in a payload is convenient and is also personal data sitting in a URL — prefer an opaque reference the server resolves.
- Don't pass entitlements. 'plan: pro-trial' should tell the app which screen to show, never grant the trial. The server decides that.
- Do pass funnel position, campaign context, and anything that only affects which screen appears.
The pattern that solves nearly all of this: put a single opaque reference in the payload, and have the app trade it for the real state over an authenticated call on first open. The link carries a pointer, and the sensitive part never leaves your server.
How do you know the handoff is working?
Instrument the seam, because this is a funnel step that fails silently — a broken handoff looks exactly like normal onboarding, just with worse numbers. Three measurements are enough to tell you whether it works and where it leaks:
| Measure | What it tells you |
|---|---|
| Handoff completion rate | Share of web starts that reached first open in the app |
| Payload arrival rate | Share of those first opens that received usable state — integration health |
| Steps replayed | How many completed steps the app made the user redo; the target is zero |
| Activation vs cold-install control | The actual lift, and the only number worth reporting |
A payload arrival rate materially below your handoff completion rate is the signal to chase first — it means users are getting to the app but the state isn't, which is usually a consent gate, an expired click window, or a routing bug rather than anything about your funnel design.
What moves
The metric is activation rate for web-originated installs, measured against a control that restarts onboarding. Removing even two redundant steps at the seam reliably lifts completed activation — and activation is the number a freemium business actually compounds on.
“Every step you make a user repeat after install is a step they're allowed to quit on.”
Ahsan
LinkTrail Engineering
Ahsan is on the LinkTrail engineering team and the engineer behind its SDKs for iOS, Android, React Native, and Flutter. He started the company after the Firebase Dynamic Links shutdown left teams with links that opened the store and forgot where the user was going — and after too many vendor calls that ended without a price. He writes here about deferred deep linking, install attribution after ATT, and the parts of the mobile growth stack the category tends to leave vague.
All posts by Ahsan