GoRouter: URL-Based Navigation for Flutter Apps
GoRouter treats your app's screens like web pages with URLs. This declarative approach simplifies deep linking and passing data via paths like `/users/123`. The footgun is forgetting its declarative nature and trying to manage state imperatively.
WHY IT EXISTS Flutter's built-in Navigator 1.0 is simple but imperative. For complex apps needing deep links, browser history, or a clear URL structure, it falls short. Navigation 2.0 was introduced to be more powerful and declarative but is notoriously complex to implement directly. GoRouter was created by the Flutter team to provide a user-friendly, URL-centric API on top of Navigation 2.0, making these advanced features accessible.
THE MENTAL MODEL Think of your app not as a stack of screens, but as a website with distinct pages, each with a unique URL. GoRouter is the web server that reads an incoming URL (like /products/1234) and decides which screen, or stack of screens, to display. All navigation logic is centralized in one place—the router configuration—making the flow of your app predictable and easy to reason about.
HOW IT WORKS You define a list of GoRoute objects when you initialize your app. Each GoRoute maps a URL pattern (like /users/:id) to a builder function that returns a widget. When you call context.go('/users/42'), GoRouter finds the matching route, extracts the parameter id: '42', and builds the corresponding screen, passing the ID as a parameter. It manages the entire navigation stack for you, automatically handling the system back button and browser history. For more complex layouts, ShellRoute can wrap your routes with a persistent UI element, like a BottomNavigationBar, that doesn't rebuild on every navigation change.
WHEN TO USE IT Use GoRouter when your app requires a robust navigation system. It's ideal for apps that need deep linking (opening a specific screen from a URL or notification), a logical URL structure for web or desktop, or complex nested navigation. It's also perfect for enforcing authentication flows, where you can redirect users from a protected route to a login screen.
WHEN NOT TO USE IT For very simple applications with only a few screens and no need for deep linking, GoRouter might be overkill. The standard Navigator.push and Navigator.pop can be simpler for basic, linear flows. If your app's navigation is purely state-driven in a way that doesn't map well to a URL structure, you might find its URL-centric approach restrictive.
ONE CANONICAL EXAMPLE A common use case is redirecting unauthenticated users. In your GoRouter configuration, you can specify a redirect function. This function checks the app's authentication state. If a user tries to access a protected route like /profile but is not logged in, the redirect function can intercept this and return /login instead, seamlessly routing them to the sign-in page.
Read the original → pub.dev
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.