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.