Deep link to a detail screen
Goal: /feed/notes/42 opens the note with back returning to the feed, and
a shared /photo/9 opens full-page over the tab bar.
Inside a tab (back stays in the tab)
Section titled “Inside a tab (back stays in the tab)”Nest the detail under its parent — its URL extends the parent’s, so the ancestor chain becomes the stack.
route('/feed', (_) => const Feed(), (_) => const FeedScreen(), children: [ route('notes/:id', (p) => Note(p('id')), (n) => NoteScreen(id: n.id)),]);/feed/notes/42 → [Feed, Note(42)]. Back pops to Feed, within the feed tab.
Full-page over the shell
Section titled “Full-page over the shell”A top-level route(...) — a sibling of the tabs(...) node — sits in a root
navigator above the tab bar.
raku(routes: [ tabs(/* feed, settings */), route('/photo/:id', (p) => Photo(p('id')), (n) => PhotoScreen(id: n.id)),]);context.push(const Photo('9')) covers the bar; back returns to the preserved
shell. context.push is level-routed automatically — you don’t choose.
From a push notification (no BuildContext)
Section titled “From a push notification (no BuildContext)”A notification carries a URL or path. Resolve it with the router you got from
raku(...) — routeOf returns null for anything your tree doesn’t know, and
never throws on garbage — then go there so the back stack is rebuilt like a
deep link:
onNotificationTap((String payload) { final route = router.routeOf(Uri.tryParse(payload) ?? Uri()); if (route != null) router.go(route); // /feed/notes/42 → [Feed, Note(42)]});Use router.push(route) instead to open it on top of where the user already is.
Notes
- Typed params arrive through your constructor:
(p) => Note(p('id')), plusp.asInt('id')andp.query('q'). Ifparsethrows on a bad value (/feed/notes/abcwithasInt), the route simply doesn’t match — the link falls through to your 404 /onUnknowninstead of crashing. - Need a multi-
:paramor?queryURL to round-trip? Add anencode:.