Skip to content

URL ⇄ stack

The core idea of raku_router’s deep linking: a URL’s path structure maps to a navigation stack — and the mapping runs both ways.

A deep link doesn’t just open a screen; its structure rebuilds the whole back history. /feed/notes/42 becomes [Feed, Note(42)], so back returns to Feed, not a rootless screen.

/feed/notes/42
Feed
Note(42)
the whole ancestor chain becomes the stack; back pops it

You declare this once, as a tree of route(...) nodes — a child’s path extends its parent’s:

raku(initial: const Home(), routes: [
route('/feed', (_) => const Feed(), (_) => const FeedScreen(), children: [
route('notes/:id', (p) => Note(p('id')), (n) => NoteScreen(id: n.id)),
]),
]);

The path’s :id arrives typed through your constructor — never params['id'].

The same tree builds a route’s URL, so navigating by a typed object updates the address bar automatically. context.push(const Note('42')) → the bar reads /feed/notes/42.

Note(42)
/feed/notes/42
one prop fills one :param automatically

For URLs with more than one :param or a ?query, give the node an encode: — the inverse of parse:

route('/orgs/:org/members/:id',
(p) => Member(p('org'), p('id')), (m) => MemberScreen(m),
encode: (m) => RoutePath({'org': m.org, 'id': m.id}));

Because the URL is the stack, three things come for free: real deep links (shareable, restore back history), browser back/forward (the browser replays your URL history — see Tabs & preserved state), and state restoration across process death.