Sub-routes
Every top-level route will create a navigation stack of one page. To produce an entire stack of pages, you can use sub-routes. In the case that a top-level route only matches part of the location, the rest of the location can be matched against sub-routes. The rules are still the same, i.e. that only a single route at any level will be matched and the entire location much be matched.
For example, the location /family/f1/person/p2
, can be made to match multiple
sub-routes to create a stack of pages:
/ => HomeScreen()
family/f1 => FamilyScreen('f1')
person/p2 => PersonScreen('f1', 'p2') ← showing this page, Back pops the stack ↑
To specify a set of pages like this, you can use sub-page routing via the
routes
parameter to the GoRoute
constructor:
final _router = GoRouter(
routes: [
GoRoute(
path: '/',
builder: (context, state) => HomeScreen(families: Families.data),
routes: [
GoRoute(
path: 'family/:fid',
builder: (context, state) {
final family = Families.family(state.params['fid']!);
return FamilyScreen(family: family);
},
routes: [
GoRoute(
path: 'person/:pid',
builder: (context, state) {
final family = Families.family(state.params['fid']!);
final person = family.person(state.params['pid']!);
return PersonScreen(family: family, person: person);
},
),
],
),
],
),
],
);
go_router will match the routes all the way down the tree of sub-routes to build up a stack of pages. If go_router doesn't find a match, then the error handler will be called.
Also, go_router will pass parameters from higher level sub-routes so that they
can be used in lower level routes, e.g. fid
is matched as part of the
family/:fid
route, but it's passed along to the person/:pid
route because
it's a sub-route of the family/:fid
route.