Flutter Navigator 2.0: Using go_router
Go beyond Flutter’s Navigator 2.0 and learn how to handle navigation with the go_router package. By Kevin D Moore.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Flutter Navigator 2.0: Using go_router
25 mins
- Getting Started
- Sneaking a Peek
- Introducing go_router
- Examining GoRouter Components
- Implementing Router
- Adding Routes
- Updating Main
- Implementing Routes
- Using Redirects
- Adding Home Routes
- Adding More Routes
- Implementing the Details Route
- Updating the Details Page
- Using Paths
- Routing in Profile Page
- Where to Go From Here?
The first version of this tutorial used a navigation system that’s pretty complicated.
Many developers — and even Google — realized the same thing. As a result, some developers wrote their packages to make the process easier. Google came out with a research paper evaluating three of the packages: VRouter, AutoRoute and Beamer.
All three of them have strengths and weaknesses. AutoRoute, for example, requires code generation. Beamer looked exciting, but it’s a bit confusing. VRouter was confusing to users due to similarly named APIs that were used in different contexts.
Another option is an intuitive and easy-to-use package called go_router.
In this tutorial, you’ll build a shopping app brilliantly called Navigation App. Through the process of building this app, you’ll learn:
- How to implement Flutter Navigator 2.0 with the go_router navigation package.
- How it can provide much more granular control for your app’s navigation.
Getting Started
Download the starter project by clicking the Download Materials button at the top or bottom of the tutorial.
The starter app is a set of screens for the shopping app. The UI doesn’t do much, but you’ll use it to navigate between pages. This set of pages — represented as screens — is in the image below:
Sneaking a Peek
The app starts with the Login page, which looks like this:
Run your app and verify it opens this page. The app will stay on this page since the navigation system isn’t yet implemented. Gradually, you’ll add code to navigate between all screens.
The flow will be:
- Start at the Login screen.
- From there, the user can log in or go to the Create Account screen.
- At the Create Account screen, the user can create an account or go back to the Login screen.
- Upon logging in, the user will be directed to the Home screen.
- The Home screen will show three screens:
- Shopping — A list of items. Selecting an item will display a details page.
- Cart — Displays the current shopping cart.
- Profile — This screen will show information related to payment, sign in and more.
- Shopping — A list of items. Selecting an item will display a details page.
- Cart — Displays the current shopping cart.
- Profile — This screen will show information related to payment, sign in and more.
Like many apps, this one requires the user to log in first before navigating around. So, you’ll want to prevent the user from going to the home screen until they have logged in.
You could check at every point that shows a page if the user has logged in and take them to the login page if they haven’t. Or, you can use some of the nice features of these routing packages to check the login state before showing a screen. Some packages call this feature guards. They guard against using a page unless the user is authorized. go_router uses the redirect
callback for this purpose.
Introducing go_router
Google introduced a new Flutter routing system that requires customized RouterDelegate
and RouterInformationParser
classes. Both of these classes take a lot of work to implement and still leave you scratching your head. Many developers decided there was an easier way to handle routing. Some decided to use their system, and others plugged into Google’s router system.
The go_router package uses Google’s router system but makes it easy to use. There are two main classes you need to use:
- GoRouter
- GoRoute
Creating a GoRouter
gives you a RouterDelegate
and a RouterInformationParser
for free. By creating this class, you can provide an initial route and the routes you need for each screen. There is even a section called redirect
that allows you to use logic to decide which route to use.
This package works on all the main platforms: Android, iOS, Mac, Windows, Linux and the Web.
Examining GoRouter Components
The GoRouter
class is made up of:
- Routes
- Error handler
- Redirect handler
For routes, GoRouter
uses a GoRoute
. This class contains a path — like a URL, an optional name that you can use instead of paths and either a page builder that returns a page or a redirect handler that redirects to another route. GoRoutes can even have sub-routes. This is where you would put pages that the parent route would call.
For example, the profile page has four pages that it launches, so it uses a sub-route for those pages. Sub-routes are a way to create a stack of pages so that the back button is shown and you can go back to the parent page. This can be as deep as you like.
You can start creating routes with the path but using names is much easier. If you were to hard-code the names in your app, you’d see login if you are using names or /login if you are using paths. If you wanted to use a deeper path, like the details page, it would look something like /main/shop/details/item. It’s easier to use names so you can use details with a parameter.
To start implementing GoRouter
, open pubspec.yaml and add the package:
go_router: ^2.2.8
Now, click the Pub get link on the top right, or from the command line type:
flutter pub get
.
Implementing Router
Create a new folder in the lib directory named router. Next, create a new dart file named routes.dart. Add the following imports. This includes all the screens and the go_router
package:
import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
import '../ui/create_account.dart';
import '../ui/error_page.dart';
import '../ui/home_screen.dart';
import '../ui/more_info.dart';
import '../ui/payment.dart';
import '../ui/personal_info.dart';
import '../ui/signin_info.dart';
import '../constants.dart';
import '../login_state.dart';
import '../ui/login.dart';
import '../ui/details.dart';
Now, create the MyRouter
class:
class MyRouter {
// 1
final LoginState loginState;
MyRouter(this.loginState);
// 2
late final router = GoRouter(
// 3
refreshListenable: loginState,
// 4
debugLogDiagnostics: true,
// 5
urlPathStrategy: UrlPathStrategy.path,
// 6
routes: [
// TODO: Add Routes
],
// TODO: Add Error Handler
// TODO Add Redirect
);
}
Here’s what’s happening in the code above:
-
LoginState
stores the user’s logged in state. - You create a variable that holds a
GoRouter
instance. - Then, you set the router to listen for changes to the
loginState
. - Show debugging logs.
- Choose the path url strategy (can use hash ‘#’).
- Define all of the routes you’ll use.
There are several properties you can set for GoRouter
. Here, you want the router to listen for changes in the login state. If the user logs out, you want the Login screen to appear. If they log in, the Home screen should appear. The debugLogDiagnostics
flag is useful to see what path you’re using and to debug any problems with your routes.
debugLogDiagnostics
flag before shipping your app.This defines the basics for using GoRouter
. Now, you’ll need three things:
- A list of all the routes to your screens.
- Error Handler. If a route comes in (maybe from a deep link), handle an invalid route.
- Any redirect logic needed for redirecting to different pages based on any current state (optional).