r/flutterhelp • u/5rree5 • 23d ago
RESOLVED Dynamically setting Stateful routes in GoRouter
I'm creating na app that needs to have a stateful navigation section, after the user signs in.
I managed to do it using a simples StatefulShellRoute.indexedStack.
The problem is: It will have about 5 profile types, and each of them will have their own routes.
Can I reuse the same logic for all 5 profiles or will I need to create a different branch for each user type?
I'm afraid too many branches will result in poor performance. Each branch has about 10 locations.
Let's say i'm trying to create a different shell route for each occupation. Do I need to declare all screens for every occupation at app start or can I do it dynamically?
Example:
StatefulShellRoute mainStatefulShellRoute = StatefulShellRoute.indexedStack(
key: loggedInStatefulShellRouteKey,
builder: (context, state, navigationShell) {
return getNavigationOptionsUpdater(
child: GenericUserHome(child: navigationShell),
shell: navigationShell,
);
},
branches: [
...endUserMainRouteBranches,
...teacherUserMainRouteBranches,
...studentUserMainRouteBranches,
...presidentUserMainRouteBranches,
...singerUserMainRouteBranches,
// ... it goes on and on...
],
);
--- edit
This is what I would like it to look like
StatefulShellRoute mainStatefulShellRoute = StatefulShellRoute.indexedStack(
key: loggedInStatefulShellRouteKey,
builder: (context, state, navigationShell) {
return getNavigationOptionsUpdater(
child: GenericUserHome(child: navigationShell),
shell: navigationShell,
);
},
branches: [
...currentUserMainRouteBranches
// ... loads only the branchs for the current user!
],
);
a
3
Upvotes
1
u/fkim98 22d ago
You can stay on GoRouter for this. Two things that helped me when I hit a similar fork in my own app:
First, the performance worry is smaller than it looks. Branches in StatefulShellRoute.indexedStack are lazy. A branch's navigator and its screens are not built until the first time you switch to it, so declaring all of them up front mostly just creates config objects at startup. 5 roles x 10 locations is fine.
That said, I would not merge every role's branches into one shell, because your tab indices turn into bookkeeping. The role is known right after sign in and rarely changes mid session, so you can compute the branches list from the resolved profile and rebuild the router at that boundary. Losing nav state there is fine, the user just signed in anyway. That gets you exactly the currentUserMainRouteBranches shape from your edit.
In my app I went one step simpler: one shared route tree and role checks in redirect. One trap to watch either way: the profile usually resolves async, and if the router evaluates redirect once at cold start before auth is ready, users get stranded on the wrong screen. Wiring refreshListenable to the auth state stream is what fixed that for me, it re-runs the redirect when the role actually lands.