Flutter's Router API: Declarative Navigation
The Router API treats navigation as state. You declare the page stack based on app state, giving you full control over URLs and the back button. This is vital for web/desktop apps but introduces significant boilerplate compared to simple push/pop navigation.
WHY IT EXISTS Flutter's original Navigator API was a simple imperative stack, making it difficult to manage the browser URL bar, handle incoming deep links, or manipulate the navigation history. The Router API (Navigator 2.0) was created to provide a powerful, declarative system for full control over the app's navigation state, making Flutter a robust choice for web and desktop platforms.
THE MENTAL MODEL Think of the Router API as a state machine for navigation. Your app's state (e.g., which user is logged in, what product is being viewed) directly determines the stack of pages shown. The Router is a pipeline that takes raw information, like a URL from the browser, and transforms it into this page stack. You don't tell it how to get to a page; you tell it what the navigation state is.
HOW IT WORKS The process involves several key components. First, a RouteInformationProvider gets routing information from the OS, like a new URL or a back button press. Second, a RouteInformationParser takes this raw information (e.g., the string "/products/123") and parses it into a structured, custom data object (e.g., ProductDetailsRoute(id: '123')). Third, the RouterDelegate receives this data object and, based on it and other app state, builds a Navigator widget with the correct list of Pages. The delegate is the brain of the operation. Finally, a BackButtonDispatcher manages back button events, delegating them to the appropriate RouterDelegate.
WHEN TO USE IT Use the Router API for any non-trivial app, especially those targeting web or desktop where URL management is critical. It's necessary for handling deep links, custom navigation transitions, and nested routing scenarios (e.g., tabs within a page that have their own navigation stack). If you need to programmatically control the entire navigation history, this is the tool.
WHEN NOT TO USE IT For very simple applications with a linear flow and no need for web support or deep linking, the original Navigator API (Navigator.push/pop) is simpler due to less boilerplate. If you find yourself writing a Parser and Delegate just to push one page, you might be over-engineering. Packages like go_router can simplify the Router API for you.
ONE CANONICAL EXAMPLE A user navigates to yourapp.com/users/42. The RouteInformationProvider reports the new route. Your RouteInformationParser converts the string "/users/42" into a UserDetailsRoute(id: '42') object. Your RouterDelegate receives this object, updates its internal state, and rebuilds its Navigator to show a HomePage with a UserDetailsPage(userId: '42') on top. The URL bar, app content, and navigation history are all perfectly in sync.
Read the original → api.flutter.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.