Flutter web routing/navigation methods
Here’s the topic for today.
“How should I route/navigate in a flutter web project?”
We’ll consider 3 types of routing methods here:
- Flutter default routing
- Dane Mackier’s routing
- Fluro routing
Flutter’s default routing
First, we need to know we need such methods for routing in flutter web projects. We’ll start with the routing/navigating method that Flutter basically provides. Here’s the link to the official tutorial on how to do that.
Here’s the copy from the tutorial.
Let’s briefly go over the code.
What this tutorial is trying to show is to go to other pages using routes
and onGenerateRoute
.
First, when you look at the class _AppState
, routes
and onGeneratedRoute
is set and each is forwarding different pages. routes
is forwarding ExtractArgumentsScreen
and onGenerateRoute
is directing to PassArgumentsScreen
.
Then, in homeScreen
, Navigator.pushNamed
is used to navigate to ExtractArgumentsScreen
or PassArgumentsScreen
.
The difference between ExtractArgumentsScreen
and PassArgumentsScreen
is how they handle the arguments (parameters). ExtractArgumentsScreen
uses
ModalRoute.of(context).settings.arguments
to call the arguments and PassArgumentsScreen
receives arguments from onGenerateRoute
like,
onGenerateRoute: (settings) {
if (settings.name == PassArgumentsScreen.routeName) {
final ScreenArguments args = settings.arguments;
return MaterialPageRoute(
builder: (context) {
return PassArgumentsScreen(
title: args.title,
message: args.message,
);
},
);
}
},
Let’s stop explaining and just run this.
When you try both buttons, it’ll still work great.
It looks great, right? Well, there are issues with it actually.
The first issue is about the URL. At least the URL from ExtractArgumentsScreen
contains the page name where PassArgumentsScreen
contains pretty much nothing.
If this is a mobile application, it’s not an issue at all. But as a web application, this is a huge deal especially if this is a commercial website. For business websites, having some data contained in the URL affect it’s SEO and that’s why it’s better to have some useful data in it. (Of course no password should be contained)
Another issue is about refreshing the page.
Let’s refresh both pages. For ExtractArgumentsScreen
, you’ll see a terrifying red screen of error. For PassArgumentsScreen
, you’ll notice that it brings you back to the first page. Of course, we’ve never intended any of these cases.
I think all these explained enough why we need extra work on routing and navigation for the Flutter web.
Now let’s look for solutions.
Dane Mackier’s routing
The first method I recommend is to use Dane Machier’s solution. This is the link to the tutorial. Flutter Web Advanced Navigation.
If all this makes sense, you can skip to the next. I just made the tutorial simpler because I know the future me still not get it.
Let’s first take a look router.dart.
One thing you’ll notice is the usage of the package called get_it
. Here’s the link to the package. This package simply allows you to access any class globally (using singleton). For example, you may initialize as,
GetIt locator = GetIt.instance;
then register the class like
locator.registerLazySingleton(() => NavigationService());
NavigationService
uses pushNamed
to pass arguments (parameters) to other pages.
Class RoutingData
and StringExtension
let URL to be separated to path and parameters and regroups as RoutingData
.
Why do we need such a thing? From the previous example, we know that pushNamed
with arguments is not visible in the URL at all. Then it’s necessary to create a new method of passing parameters into the URL.
The future me might ask,
“What’s that extension StringExtension on String?”
This simply extends the functionality of String. It’s not limited to routing or navigating but it’s just expanding String methods. As the result, you may notice that all String types of values have getRoutingData
method.
For more info about the extension, click here.
Now let’s run this.
Please forget about the ugly UI. Let’s click on the button ‘Go to demo router’.
Please notice that ‘Message from home’ is passed argument from home.
Also, refresh works as expected when you try it.
Fluro routing
Fluro
is a package that makes routing and navigation easier. For more info about the package, click here.
We’ll go over how to use it.
First, router.define
connects the path string and a Handler.
Then you need to set the widget page with arguments in Handlers.
For example, when you move to another page from the HomePage with parameters, all you need to do is to make a completed URL and send it out using navigateTo
.
String route1 = “/second?message=helloThere”;
Application.router.navigateTo(context, route1);
Then when you receive the parameter from the page /second
, you can do something like,
String message = params[‘message’].first ?? ‘No message’;
How convenient. 😄
Conclusion
As a conclusion, you might have to choose whichever that makes more sense for you. Dane Mackier’s routing uses fewer packages (except get_it) and therefore it’s much reliable to flutter updates. Also, it’s highly customizable.
Fluro is more like a ready-to-go routing. It provides multiple transitions between pages and also supports function handlers.