How does go_router simplify navigation in Flutter?
// short answer
go_router lets you define your app's routes as a declarative table mapping URL paths to pages, handling deep linking, web URL sync, and nested/shell routes without writing raw Navigator 2.0 boilerplate.
You define a GoRouter with a list of GoRoute entries, each specifying a path and a builder returning the page widget for that path — including path parameters (/users/:id) and query parameters, both accessible via state. Navigating is as simple as context.go('/users/5') or context.push('/settings'), and go_router keeps the browser URL in sync automatically on Flutter Web.
It also supports ShellRoute for persistent UI (like a bottom nav bar that stays while inner content changes) and redirect logic (e.g. redirecting to login if unauthenticated), both notoriously fiddly to implement correctly with raw Navigator 2.0.
// code example
final router = GoRouter(
routes: [
GoRoute(path: '/', builder: (context, state) => const HomeScreen()),
GoRoute(
path: '/users/:id',
builder: (context, state) {
final id = state.pathParameters['id']!;
return UserScreen(userId: id);
},
),
],
);
// Navigate
context.go('/users/5');// common mistakes
- ×Mixing go_router navigation with raw Navigator.push in the same app inconsistently, causing confusing back-stack behavior.
- ×Not using redirect for auth guarding and instead manually checking auth state in every screen's initState.