ArchitectureMedium30 XP4 min read
How do you architect routing in a Flutter app with go_router?
TL;DR: Use go_router with a top-level GoRouter instance configured in a provider/singleton. Define routes declaratively with GoRoute. Use redirect for auth guards. ShellRoute for persistent bottom nav. Pass state via extra or use a BLoC/Riverpod provider.
Full Answer
- ▸Declarative routes: GoRoute(path: '/quiz/:id', builder: ...) — URL-first approach
- ▸Auth redirect: redirect: (ctx, state) — return '/login' if not authenticated
- ▸ShellRoute: Wrap routes that share a Scaffold (bottom navigation bar stays visible)
- ▸Extra parameter: GoRouter.of(ctx).push('/quiz', extra: quizConfig) — pass objects
- ▸refreshListenable: GoRouter rebuilds when auth state changes (Listenable)
🎯
Use refreshListenable with your AuthBloc/AuthNotifier. When the user logs out, the router automatically redirects to /login without manual navigation calls.
Code Examples
dartgo_router with auth guard and ShellRoute
Output
// Unauthenticated requests redirect to /login automatically // ShellRoute keeps AppShell (nav bar) mounted across routes
Common Mistakes
- ✗Using Navigator.push inside BLoC event handlers — routing is a UI concern, not business logic
- ✗Passing complex state as path parameters — use extra: for objects, reserve path params for IDs
Interview Tip
💡
go_router is the Flutter team's recommended router. Know that it uses the Navigator 2.0 (Router widget) API under the hood, enabling declarative URL-based navigation and deep links.
#go_router#routing#deep-link#guard#shell-route