Navigation and routing take just too much code and effort to implement. No matter if you implement a router yourself or you use a library like fluro or sailor, there's still a lot of boilerplate. All of this changes with the auto_route package which works elegantly by code generation. This way, you can reduce repetitive and error-prone code to a minimum while still having the ability to customize the routes to your heart's content.
What we will build
The starter project contains the individual page widgets already pre-built so that we can focus purely on navigation. At the end of this tutorial, we'll have an app with three routes, custom route arguments and custom transitions.
Adding dependencies
To follow along with this tutorial, use the same versions of the packages to make sure we're on the same page.
pubspec.yaml
dependencies:
flutter:
sdk: flutter
auto_route: ^0.2.1
dev_dependencies:
flutter_test:
sdk: flutter
build_runner:
auto_route_generator: ^0.2.1+3
The Router class
The center point of navigation with the auto_route library is a class annotated with @autoRouter
. In its simplest yet fully functional form, the router class takes only a few lines of code.
routes/router.dart
@autoRouter
class $Router {
InitialPage initialPage;
SecondPage secondPage;
ThirdPage thirdPage;
}
part 'router.g.dart';
statement as you might be used to from other code gen packages. That's because the generated classes don't use the any members of our manually written class, hence, the generated file is not a "part" of the manually written file.While even this simplest will work perfectly fine for basic routing, we can make the generated name of the InitialPage
be a slash '/'
as usual by annotating it with @initial
.
routes/router.dart
@autoRouter
class $Router {
@initial
InitialPage initialPage;
SecondPage secondPage;
ThirdPage thirdPage;
}
After running every Flutter developer's favorite command, we'll have a generated router.gr.dart file.
?? terminal
flutter pub run build_runner watch --delete-conflicting-outputs
Plugging the Router into Flutter
The generated class contains three main things:
- names of the routes as constant strings
onGenerateRoute
method which handles navigation arguments out of the box (more on that below)- a
navigatorKey
&navigator
properties used for navigating without passing around theBuildContext
Let's plug this all into the MaterialApp
or CupertinoApp
widget.
main.dart
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Material App',
initialRoute: Router.initialPage,
onGenerateRoute: Router.onGenerateRoute,
navigatorKey: Router.navigatorKey,
);
}
}
$Router
class which we've defined ourselves. Always use the generated class without the dollar sign.Single-argument routes ☝
The SecondPage
widget takes in a single argument into its constructor
pages/second_page.dart
class SecondPage extends StatelessWidget {
final String userId;
const SecondPage({@required this.userId});
...
}
When auto_route sees a single-parameter constructor, it will make sure that the passed-in argument present and that it is of the correct type. Since auto_route uses the default navigator API with named routes, passing arguments to a new route uses the arguments
parameter of the pushNamed
method. Let's add the navigation code to the "Go to SECOND" button callback inside initial_page.dart!
pages/initial_page.dart
void navigateToSecond(BuildContext context) {
Router.navigator.pushNamed(Router.secondPage, arguments: 'unique_user_id');
}
We can easily navigate without passing in the BuildContext
by the virtue of the navigatorKey
which we specified in main.dart. Additionally, if we pass in an argument of a wrong type or we leave it out completely, a prominent error page will be displayed.

@required
, leaving out arguments
completely wouldn't be an issue. Type checking would still occur though, which is good.Multi-argument routes ?
The ThirdPage
takes in two arguments:
pages/third_page.dart
class ThirdPage extends StatelessWidget {
final String userName;
final int points;
const ThirdPage({
@required this.userName,
@required this.points,
});
}
Will we be forced to use a Map<String, dynamic>
by the auto_route package? ?
Nope! ? The package will generate a ThirdPageArguments
class honoring any @required
annotations or default values there may be in the constructor. Now we can navigate to the third page from initial_page.dart.
pages/initial_page.dart
void navigateToThird(BuildContext context) {
Router.navigator.pushNamed(
Router.thirdPage,
arguments: ThirdPageArguments(points: 123, userName: 'Bob'),
);
}
ThirdPageArguments
is the only type accepted by the generated Router
. Passing in anything else will result in an error.
@required
, not passing in the generated 'PageName'Arguments
object will result in an error.Customizing routes
Our $Router
class is currently pretty lean.
routes/router.dart
@autoRouter
class $Router {
@initial
InitialPage initialPage;
SecondPage secondPage;
ThirdPage thirdPage;
}
Navigating to any of the routes is equivalent to instantiating the simplest MaterialPageRoute
without any additional configuration. Let's change that!
Passing in custom arguments, for example the fullscreenDialog
boolean, is possible with @MaterialRoute
or @CupertinoRoute
annotations. The following will make the SecondPage
appear with a cross instead of the back arrow in the AppBar
.
routes/router.dart
@MaterialRoute(fullscreenDialog: true)
SecondPage secondPage;
Should you want to use neither material design nor cupertino for your routes, you can annotate the route with @CustomRoute
which instantiates a PageRouteBuilder
behind the scenes. Among other things, this allows you to specify custom transitions.
routes/router.dart
@CustomRoute(
transitionsBuilder: TransitionsBuilders.zoomIn,
durationInMilliseconds: 200,
)
ThirdPage thirdPage;
TransitionsBuilders
comes from auto_route and it has a bunch of functions pre-defined. You can also create your own transition animations by using the default functions as a template.
It's truly invigorating to see the whole Flutter package ecosystem become more mature. The auto_route package surely contributes a ton to developer productivity and happiness since handling routing manually is a toilsome endeavor. Be sure to show the author, Milad Akarie, some support by giving this package a like on pub.dev and a star on GitHub!
It seems like CustomRoute’s usefulness is limited by its transitions builder’s signature – so this doesn’t allow for animations to the “previous route” when navigating to a new route.
Unless I am missing something, it seems like this package doesn’t support transitions like “make OldPage exit left while NewPage enters from the right”.
Your reasoning seems correct.
thanks for yet another great Flutter tutorial ! are you able to add a segment showing how it could be used to maintain navigation state when using a bottom nav bar ?
Thank you for a great tutorial and route package!
Fantastic tutorial, thank you very much.
After I used the Router class, a lot of Router class members can’t found??
Great tutorial, Matt! I’m playing with RouteGuard but I’m in a bit of a dilemma: in the documentation it says that the main() method is a good place to register RouteGuards but my RouteGuard class depends on an object that Provider instantiates inside MyApp widget, so when my RouteGuard object is instantiated Provider.of cannot find the dependency yet and an error is thrown. I tried to instantiate my Provider before runApp(MyApp()) but I get all sort of errors. Am I making sense?
Never mind. I found a suitable place where it makes sense to register the RouteGuards.
currently (as of May 2020) , auto route doesn’t support generating route class parameters that are functions (callbacks functions) .
Am i right ?
Can the initial page be changed? like I want to show a welcome screen as initial page for the first time only when he / she opens the app.
Hii,
I am currently using flutter and trying to create a responsive web ui. I watched your tutorial on the named Routes and onGenerate I followed it and then implemented all that taught in the video for the desktop layout and it worked great but not on the same for mobile layout. But my question to you is ….can I use the same onGenerate class again for the mobile layout too if yes then how??? and what is the use of global key here.Sorry if am being rude.
thank you
Hi resocoder, very nice tutorial, but it seems that auto_route library has changed a lot over time with many additional supports such as extendedNavigator, route guard and many more things. Please make a newer tutorial for that
Hi Matt ! I am using Firebase FireAth and Firestore, My pattern is your teach DDD, my user must have others field such firstname, lastname and others, for edit these informamtions I create an EditFormPage with constructor argument, but for naviging to this page I must provide user object who is connected. Here is my problem. Can you help me ? Please !
it is not working currently, could you please make full tutorial on flutter route?
It seems to be outdated sunce I looking on the documentation and it changed a lot.
Thanks for your always useful tutorials.
Thank you for your sharing. I am worried that I lack creative ideas. It is your article that makes me full of hope. Thank you. But, I have a question, can you help me?
Thanks for sharing. I read many of your blog posts, cool, your blog is very good.
Can you be more specific about the content of your article? After reading it, I still have some doubts. Hope you can help me.
Can you be more specific about the content of your article? After reading it, I still have some doubts. Hope you can help me.