Navigation and routing
Flutter provides a complete system for navigating between screens and handling deep links. Small applications without complex deep linking can use Navigator
, while apps with specific deep linking and navigation requirements should also use the Router
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, see Deep linking.
Using the Navigator
#The Navigator
widget displays screens as a stack using the correct transition animations for the target platform. To navigate to a new screen, access the Navigator
through the route's BuildContext
and call imperative methods such as push()
or pop()
:
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => const SongScreen(song: song),
),
);
},
child: Text(song.name),
Because Navigator
keeps a stack of Route
objects (representing the history stack), The push()
method also takes a Route
object. The MaterialPageRoute
object is a subclass of Route
that specifies the transition animations for Material Design. For more examples of how to use the Navigator
, follow the navigation recipes from the Flutter Cookbook or visit the Navigator API documentation.
Using named routes
#Applications with simple navigation and deep linking requirements can use the Navigator
for navigation and the MaterialApp.routes
parameter for deep links:
@override
Widget build(BuildContext context) {
return MaterialApp(
routes: {
'/': (context) => HomeScreen(),
'/details': (context) => DetailScreen(),
},
);
}
Routes specified here are called named routes. For a complete example, follow the Navigate 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 new Route
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.
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 multiple Navigator
widgets) should use a routing package such as go_router that can parse the route path and configure the Navigator
whenever the app receives a new deep link.
To use the Router, switch to the router
constructor on MaterialApp
or CupertinoApp
and provide it with a Router
configuration. Routing packages, such as go_router, typically provide a configuration for you. For example:
MaterialApp.router(
routerConfig: GoRouter(
// …
)
);
Because packages like go_router are declarative, they will always display the same screen(s) when a deep link is received.
Using Router and Navigator together
#The Router
and Navigator
are designed to work together. You can navigate using the Router
API through a declarative routing package, such as go_router
, or by calling imperative methods such as push()
and pop()
on the Navigator
.
When you navigate using the Router
or a declarative routing package, each route on the Navigator is page-backed, meaning it was created from a Page
using the pages
argument on the Navigator
constructor. Conversely, any Route
created by calling Navigator.push
or showDialog
will add a pageless route to the Navigator. If you are using a routing package, Routes that are page-backed are always deep-linkable, whereas pageless routes are not.
When a page-backed Route
is removed from the Navigator
, all of the pageless routes after it are also removed. For example, if a deep link navigates by removing a page-backed route from the Navigator, all pageless routes after (up until the next page-backed route) are removed too.
Web support
#Apps using the Router
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 the Router
, a History API entry is added to the browser's history stack. Pressing the back button uses reverse chronological navigation, meaning that the user is taken to the previously visited location that was shown using the Router
. This means that if the user pops a page from the Navigator
and then presses the browser back 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 multiple navigation recipes that show how to use the
Navigator
. - The
Navigator
andRouter
API 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
Router
widget directly, without a routing package. - The Router design document contains the motivation and design of the Router` API.
Unless stated otherwise, the documentation on this site reflects the latest stable version of Flutter. Page last updated on 2024-07-18. View source or report an issue.