![](/style/images/good.png)
![](/style/images/bad.png)
Using Flutter’s Navigator 2.0 with Voyager | Flutter Community
source link: https://medium.com/flutter-community/using-flutters-navigator-2-0-with-voyager-router-66728fc4e56b
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
![Image for post](https://miro.medium.com/max/60/1*KdxShkt9KB9bCbSJ2lPS9w.png?q=20)
Learn how to use Voyager library and Navigator 2.0 API together. Benefit from Flutter’s new features like browser history and declarative navigation without the need for all the boilerplate code.
The Problem: Navigator 2.0 Complexity
The new Navigator API is a fairly recent addition to Flutter. If you haven’t heard about it before I highly recommend checking this article by John Ryan: Learning Flutter’s new navigation and routing system.
![Image for post](https://miro.medium.com/max/60/1*ZlZJtAcfpqjPO2RsS79pcA.png?q=20)
Needless to state the above looks complex. There is even an issue to make it simpler. You might quickly get overwhelmed by all the boilerplate code you need to put in first. While the new API is definitely powerful, getting everything right is a challenge.
If you just use Navigator and pages, the API is quite straightforward and declarative. Just state your pages and behold.
Unfortunately, as soon as you try using MaterialApp.router things get more complicated. You need to create RouterDelegate and RouteInformationParser. Your pages get encapsulated inside what one would call a controller. This is no longer declarative approach. You end up with an API similar to Navigator 1.0.
The Solution: Keep It Declarative, Simple.
Voyager builds on top of this new API and tries to make developer experience nicer.
Here’s how we could use Voyager with the plain Navigator.
![Image for post](https://miro.medium.com/max/60/1*s3oQSflVts1K828vZlscDQ.png?q=20)
As a precondition, we need to have Voyager’s router loaded (more info here). Once that is done, you can use the router instance with a VoyagerStack. The stack’s method asPages returns List<Page<dynamic>> instance that the Navigator is expecting.
If you plan to use the stack with the MaterialApp, you don’t need to worry about instigating the delegate and the information parser — just use VoyagerStackApp instead:
![Image for post](https://miro.medium.com/max/60/1*wc8kqGATZHzfX_DtiLyGoQ.png?q=20)
Put your MaterialApp within a createApp builder and handle system events from callbacks as you see fit. No need to worry about the delegate and your navigation stays declarative.
Nonetheless, if you prefer the imperative approach, you have an option to use VoyagerInformationParser and VoyagerDelegate directly:
![Image for post](https://miro.medium.com/max/60/1*-uxn4qI2VDW8mJNPIj4BWQ.png?q=20)
Page Arguments and Scopes
The VoyagerStack can contain not only pages but also other stacks. Pages can take arguments, stacks can take scopes.
![Image for post](https://miro.medium.com/max/60/1*B5PbAZvcHlrluFEGu5_r5Q.png?q=20)
In the above snippet, we’re providing a Bloc instance across multiple pages at once. This can be helpful when building complex flows that need to share common state.
Stack Serialization
You might not need stack serialization. This is only needed if you want to support browser history and have custom types in your stack (e.g. Bloc used as a scope). Since Flutter has no reflection, we need to register non-standard types manually — in our case it’s the LoginBloc:
![Image for post](https://miro.medium.com/max/60/1*f1fbuxejj6Ldu6WQf0iAlw.png?q=20)
Under the hood the VoyagerInformationParser will use registered adapters to persist the stack.
Stack Manipulation
The stack object is immutable. If you wish to modify the stack contents, you need to use mutate method:
![Image for post](https://miro.medium.com/max/60/1*IBDsrAhUAo-9I3-bPmo-gQ.png?q=20)
This method gives you a copy of the underlying array which you can modify. For convenience, the stack comes with predefined removeLast method:
![Image for post](https://miro.medium.com/max/60/1*Ml7l9_P9H2GtlRemQBqG7w.png?q=20)
Unlike List.removeLast, this method removes nested stacks recursively. Additionally the scope element can implement VoyagerScopeRemovable — using VoyagerStack.removeLast can trigger resources disposal automatically.
Page Animations
By default all stack pages are wrapped with a MaterialPage when you call asPages method. If needed, you can provide your own wrapper using defaultPageBuilder parameter:
![Image for post](https://miro.medium.com/max/60/1*FCgjwTAdWPG6UZ8qs_azvA.png?q=20)
For finer control, you can register PagePlugin. This will make page wrapping a part of your navigation schema, customizable per each destination. Say we wanted to animate login screen from the bottom, this is what it could look like:
![Image for post](https://miro.medium.com/max/60/1*bcBxcmzWdaCvqZzlizMVkg.png?q=20)
Learn More
Check all the implementation details in the project’s example app. If you wish to try out Voyager with latest Navigator 2.0 API, you’ll need a 3.x version (a nullsafety prerelease):
Want to more about Voyager? Check the talk I gave during Droidcon SF 2019 — it’s a bit outdated now but it still contains relevant information about the core architecture.
Finally, don’t forget to check the project on GitHub — leave a ⭐, create an issue if you find a problem or open a PR. Thank you for your reading time 💖
🔗 Follow Flutter Community on Twitter: https://www.twitter.com/FlutterComm
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK