Deep Links
One line of config makes every route reachable from outside the app.
Turning it on
# whitehall.toml
[android]
deep_link = "myapp" A link then maps onto your routes exactly as they are already written. No separate table, no second set of paths to keep in sync:
myapp:///user/42 → src/routes/user/[id]/+screen.wh
myapp:///show/tt0903747 → src/routes/show/[id]/+screen.wh Read the segment the usual way, with $screen.params. A widget's tap uses the same scheme.
What it generates
Three things, all of which you would otherwise write by hand:
- a
VIEW+DEFAULT+BROWSABLEintent filter, which is what makes a browser willing to hand the link over launchMode="singleTask", so a link arriving while the app is already running does not start a second copy of itonNewIntentrouting, which is what actually navigates that already-running app to the linked route
Cold starts get a back stack
Following a link into an app that was not running is the case that usually goes wrong: the user lands three levels deep, presses back, and the app closes. Whitehall seeds the back stack for the linked route, so back walks up the hierarchy the way it would have if they had navigated there themselves.
myapp:///user/42 are not a typo — the host is empty, so the
path starts right after it. myapp://user/42 would read user as the
host and /42 as the whole path.Testing one
adb shell am start -a android.intent.action.VIEW -d "myapp:///user/42" myapp://, and
Android will ask the user to choose. For a link that must be yours, use an https:// App Link instead:# whitehall.toml
[android]
app_link = "example.com" https://example.com/user/42 then opens /user/[id] directly, with no
chooser. Whitehall writes the autoVerify intent filter; serving https://example.com/.well-known/assetlinks.json, the file Android checks to
confirm you own the domain, is yours.
See Also
- $navigate — routing inside the app
- $screen — reading parameters out of a link
- Configuration — the
[android]table