Flutter 3.41 is live! Check out theFlutter 3.41 blog post!
Navigation and routing
Overview of Flutter's navigation and routing features
Flutter provides a complete system for navigating between screens and handling deep links. Small applications without complex deep linking can useNavigator, while apps with specific deep linking and navigation requirements should also use theRouter to correctly handle deep links on Android and iOS, and to stay in sync with the address bar when the app is running on the web.
To configure your Android or iOS application to handle deep links, seeDeep linking.
Using the Navigator
# TheNavigator widget displays screens as a stack using the correct transition animations for the target platform. To navigate to a new screen, access theNavigator through the route'sBuildContext and call imperative methods such aspush()or pop():
child:constText('Open second screen'),onPressed:(){Navigator.of(context).push(MaterialPageRoute<void>(builder:(context)=>constSecondScreen(),),);}, BecauseNavigator keeps a stack ofRoute objects (representing the history stack), Thepush() method also takes aRoute object. TheMaterialPageRoute object is a subclass ofRoute that specifies the transition animations for Material Design. For more examples of how to use theNavigator, follow thenavigation recipes from the Flutter Cookbook or visit theNavigator API documentation.
Using named routes
# We don't recommend using named routes for most applications. Instead, usego_router (or another routing package) or useNavigator withMaterialPageRoute. For more information, see theLimitations section.
Applications with simple navigation and deep linking requirements can use theNavigator for navigation and theMaterialApp.routes parameter for deep links:
child:constText('Open second screen'),onPressed:(){Navigator.pushNamed(context,'/second');},/second represents anamed route that was declared in theMaterialApp.routes list. For a complete example, follow theNavigate with named routes recipe from the Flutter Cookbook.
Limitations
# Although named routes can handle deep links, the behavior is always the same and can't be customized. When a new deep link is received by the platform, Flutter pushes a newRoute onto the Navigator regardless of where the user currently is.
Flutter also doesn't support the browser forward button for applications using named routes. For these reasons, we don't recommend using named routes in most applications. Instead, use a routing package likego_router or useNavigator withMaterialPageRoute.
Using the Router
# Flutter applications with advanced navigation and routing requirements (such as a web app that uses direct links to each screen, or an app with multipleNavigator widgets) should use a routing package such asgo_router that can parse the route path and configure theNavigator whenever the app receives a new deep link.
To use the Router, switch to therouter constructor onMaterialApp orCupertinoApp and provide it with aRouter configuration. Routing packages, such asgo_router, typically provide route configuration and routes can be used as follows:
child:constText('Open second screen'),onPressed:()=>context.go('/second'),Because packages like go_router aredeclarative, they will always display the same screen(s) when a deep link is received.
If you prefer not to use a routing package and would like full control over navigation and routing in your app, overrideRouteInformationParser andRouterDelegate. When the state in your app changes, you can precisely control the stack of screens by providing a list ofPage objects using theNavigator.pages parameter. For more details, see theRouter API documentation.
Using Router and Navigator together
# TheRouter andNavigator are designed to work together. You can navigate using theRouter API through a declarative routing package, such asgo_router, or by calling imperative methods such aspush() andpop() on theNavigator.
When you navigate using theRouter or a declarative routing package, each route on the Navigator ispage-backed, meaning it was created from aPage using thepages argument on theNavigator constructor. Conversely, anyRoute created by callingNavigator.push orshowDialog will add apageless route to the Navigator. If you are using a routing package, Routes that arepage-backed are always deep-linkable, whereaspageless routes are not.
When apage-backedRoute is removed from theNavigator, all of thepageless routes after it are also removed. For example, if a deep link navigates by removing apage-backed route from the Navigator, allpageless routes after (up until the nextpage-backed route) are removed too.
You can't prevent navigation from page-backed screens usingWillPopScope. Instead, you should consult your routing package's API documentation.
Web support
# Apps using theRouter class integrate with the browser History API to provide a consistent experience when using the browser's back and forward buttons. Whenever you navigate using theRouter, a History API entry is added to the browser's history stack. Pressing theback button usesreverse chronological navigation, meaning that the user is taken to the previously visited location that was shown using theRouter. This means that if the user pops a page from theNavigator and then presses the browserback button the previous page is pushed back onto the stack.
More information
#For more information on navigation and routing, check out the following resources:
- The Flutter cookbook includes multiplenavigation recipes that show how to use the
Navigator. - The
NavigatorandRouterAPI documentation contain details on how to set up declarative navigation without a routing package. - Understanding navigation, a page from the Material Design documentation, outlines concepts for designing the navigation in your app, including explanations for forward, upward, and chronological navigation.
- Learning Flutter's new navigation and routing system, an article on Medium, describes how to use the
Routerwidget directly, without a routing package. - TheRouter design document contains the motivation and design of the
RouterAPI.
Unless stated otherwise, the documentation on this site reflects Flutter 3.38.6. Page last updated on 2025-12-08.View source orreport an issue.