Deep Links
Overview
Section titled “Overview”Trace delivers deep links to your app in two scenarios:
- Direct deep links — user clicks a Trace short link while the app is installed. The link opens the app directly.
- Deferred deep links — user clicks a link, installs the app, then opens it for the first time. Trace delivers the deep link payload after attribution.
Both arrive through the same listener.
Setting up the listener
Section titled “Setting up the listener”TraceAndroid.setDeepLinkListener { deepLink -> val path = deepLink.path // "/product/123" val params = deepLink.params // {"color": "blue"} val deferred = deepLink.isDeferred // true if from install attribution
navigateTo(path, params)}TraceClient.shared.setDeepLinkListener { deepLink in let path = deepLink.path let params = deepLink.params let deferred = deepLink.isDeferred
navigateTo(path, params)}Type-safe routing (Android Navigation3)
Section titled “Type-safe routing (Android Navigation3)”For Compose apps, use the deep link mapper to convert paths into typed route objects:
val mapper = rememberDeepLinkMapper { link("/product/{id}") { params -> ProductRoute(id = params.require("id")) } link("/invite/{code}") { params -> InviteRoute(code = params.require("code")) } link("/settings") { SettingsRoute }}Then wire it into your navigation:
TraceProvider { val decorator = rememberTraceEntryDecorator( backStack = backStack, routeMapper = mapper )
NavDisplay( backStack = backStack, entryDecorators = listOf(decorator) )}When a deep link arrives with path /product/abc, the mapper calls your lambda and pushes ProductRoute(id = "abc") onto the back stack.
Path parameters
Section titled “Path parameters”Use {name} in the path pattern to capture segments:
link("/product/{id}") { params -> // params.require("id") → "abc"}
link("/category/{cat}/item/{item}") { params -> // params.require("cat") → "electronics" // params.require("item") → "phone-123"}Query parameters
Section titled “Query parameters”Query parameters from deepLinkParams are also available:
// Link created with: deepLinkPath="/product/123", deepLinkParams={"color": "blue"}link("/product/{id}") { params -> val id = params.require("id") // "123" val color = params["color"] // "blue" ProductRoute(id, color)}Typed accessors
Section titled “Typed accessors”| Method | Return type | Behavior |
|---|---|---|
params["key"] | String? | Returns null if missing |
params.require("key") | String | Throws if missing |
params.int("key") | Int? | Parses to Int, null if missing or invalid |
params.long("key") | Long? | Parses to Long |
params.boolean("key") | Boolean? | Parses to Boolean |
Auth gates
Section titled “Auth gates”Deferred deep links often arrive before the user has signed in. Use an auth gate to hold the deep link until the user is authenticated:
val decorator = rememberTraceEntryDecorator( backStack = backStack, routeMapper = mapper, authGate = { isLoggedIn } // deep link waits until this returns true)The flow:
- User clicks campaign link → installs app → opens app
- SDK receives deferred deep link for
/invite/abc authGatereturnsfalse(user not logged in yet) → deep link is parked- User signs up or logs in →
authGatereturnstrue - Deep link is delivered →
InviteRoute(code = "abc")pushed to back stack
Creating links with deep link payloads
Section titled “Creating links with deep link payloads”When creating short links via the API, specify the deep link data:
curl -X POST https://api.traceclick.io/v1/links \ -H "X-Api-Key: tr_live_xxxxxxxxxxxx" \ -H "Content-Type: application/json" \ -d '{ "deepLinkPath": "/product/123", "deepLinkParams": {"color": "blue", "ref": "email"}, "campaignId": "summer_sale", "fallbackUrl": "https://yourapp.com/product/123" }'When this link drives an install, the SDK delivers:
path = "/product/123"params = {"color": "blue", "ref": "email"}isDeferred = true