A newbie’s information to go_router in Flutter


Written by Hrishikesh Pathak

Routing is a vital facet of an app. Similar to if you handle the appliance state or construct the UI, you need to give ample consideration to optimizing the routing of your software. An optimized routing system helps customers navigate your app and may deal with the person state effectively.

In Flutter, there are a number of approaches to routing. Certainly one of them is go_Router – a declarative and minimal routing system constructed on high of Flutter’s Router API. go_router supplies a handy URL-based API to navigate between completely different screens.

On this article, we’ll enable you learn to use go_router in Flutter. We’ll talk about the right way to use route parameters, navigate utilizing named routes, deal with 404 errors, and rather more. To get probably the most out of this text, make sure you learn it to the top.

Please comply with this GitHub hyperlink for the supply code to comply with alongside.

Including go_router to your Flutter venture

Open a terminal in your Flutter venture. Then run the next command to put in the go_router bundle in your Flutter venture.

flutter pub add go_router

This command installs the newest model of go_router in your venture. If you wish to set up a distinct model, simply change the model quantity within the pubspec.yaml file, and run flutter pub get to get your required model.

Organising fundamental routing utilizing go_router

To combine go_router in your app, change your MaterialApp widget to MaterialApp.router. This constructor accepts a routerConfig property.

MaterialApp.router(
  routerConfig: _router,
  title: "Go router",
);

Subsequent, we’ll add a GoRouter object _router to the routerConfig property. Let’s configure our GoRouter and add the dwelling and settings routes.

remaining GoRouter _router = GoRouter(
  routes: [
    GoRoute(
      path: "/",
      builder: (context, state) => const HomePage(),
    ),
    GoRoute(
      path: "/settings",
      builder: (context, state) => const SettingsPage(),
    )
  ],
);

When somebody visits the / route, GoRouter returns the HomePage widget. Equally, if somebody visits the /settings route, GoRouter returns the SettingsPage widget.

Let’s see what HomePage and SettingsPage appear to be within the code.

class HomePage extends StatelessWidget {
  const HomePage({tremendous.key});

  @override
  Widget construct(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Textual content("Homepage"),
      ),
      physique: Middle(
        baby: ElevatedButton(
        ),
      ),
    );
  }
}

class SettingsPage extends StatelessWidget {
  const SettingsPage({tremendous.key});

  @override
  Widget construct(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        automaticallyImplyLeading: true,
        title: const Textual content("Settings"),
      ),
      physique: const Middle(
        baby: Textual content("Settings Web page"),
      ),
    );
  }
}

Find out how to navigate between routes with go_router

To navigate between routes, we will use the GoRouter.of(context).go() technique or the extra concise context.go() technique. Let’s add this technique within the ElevatedButton in our HomePage widget to navigate to the /settings route.

baby: ElevatedButton(
  onPressed: () => context.go("/settings"),
  baby: const Textual content("Go to Settings web page"),
),

Equally, add an ElevatedButton within the SettingsPage to come back again to the house / route.

baby: ElevatedButton(
  onPressed: () => context.go("/"),
  baby: const Textual content("Go to dwelling web page"),
),

Subroutes in go_router

Within the above part, we outline our GoRouter object. There, you’ll be able to observe that we put a number one / in each route. When you want deeply nested routes, then it’s important to sort the entire route with the main / each time. This additionally makes the routes much less organized.

GoRouter supplies a routes argument in each GoRoute object to group subroutes and outline nested routes extra simply.

If we convert our earlier GoRouter object to a subroutes construction, then the brand new GoRouter ought to appear to be this.

remaining GoRouter _router = GoRouter(
  routes: [
    GoRoute(
      path: "/",
      builder: (context, state) => const HomePage(),
      routes: [
        GoRoute(
          path: "settings",
          builder: (context, state) => const SettingsPage(),
        )
      ],
    ),
  ],
);

Are you able to see the distinction? Now, the settings routes stay contained in the / routes. Subsequently, there’s no must specify a number one / in subroutes.

Let’s take a look at one other instance in order that we will grasp the idea fully. If you wish to outline the nested route /a/b/c, then the GoRouter object ought to appear to be this.

remaining GoRouter _newRouter = GoRouter(
  routes: [
    GoRoute(
      path: "/",
      builder: (context, state) => const HomePage(),
      routes: [
        GoRoute(
          path: "a",
          builder: (context, state) => const PageA(),
          routes: [
            GoRoute(
              path: "b",
              builder: (context, state) => PageB(),
              routes: [
                GoRoute(
                  path: "c",
                  builder: (context, state) => PageC(),
                )
              ],
            )
          ],
        )
      ],
    )
  ],
);

Including route parameters in go_router

It is rather simple so as to add route parameters in go_router. To outline a route parameter, add a trailing : with the parameter title within the path argument of GoRoute.

For instance, if you wish to add a title parameter within the settings route, the path argument needs to be /settings:title. You’ll be able to entry the route parameter with the state.params["name"] variable.

Let’s see the right way to implement this in our Flutter app. The modified GoRouter with a route parameter within the settings route ought to appear to be this.

remaining GoRouter _router = GoRouter(
  routes: [
    GoRoute(
      path: "/",
      builder: (context, state) => const HomePage(),
      routes: [
        GoRoute(
          path: "settings/:name",
          builder: (context, state) => SettingsPage(
            name: state.params["name"]!,
          ),
        )
      ],
    ),
  ],
);

To obtain the route parameter within the settings display screen, let’s modify our code and add a property known as title.

class SettingsPage extends StatelessWidget {
  remaining String title;

  const SettingsPage({tremendous.key, required this.title});

  @override
  Widget construct(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        automaticallyImplyLeading: true,
        title: Textual content(title),
      ),
      physique: Middle(
        baby: ElevatedButton(
          onPressed: () => context.go("/"),
          baby: const Textual content("Go to dwelling web page"),
        ),
      ),
    );
  }
}

Now, after we go to /settings/codemagic, the codemagic route parameter is handed to the SettingsPage and shows the variable on the display screen. Equally, in case you go to the /settings/hrishikesh route, hrishikesh is displayed within the SettingsPage.

Named routes in go_router

Writing route paths manually is cumbersome and error inclined. Subsequently, go_router provides a named route function to navigate across the app, and go_router will routinely resolve the trail itself.

To generate named routes, let’s change our GoRouter configuration with the title parameter.

remaining GoRouter _router = GoRouter(
  routes: [
    GoRoute(
      name: "home",
      path: "/",
      builder: (context, state) => const HomePage(),
      routes: [
        GoRoute(
          name: "settings",
          path: "settings/:name",
          builder: (context, state) => SettingsPage(
            name: state.params["name"]!,
          ),
        )
      ],
    ),
  ],
);

Passing route parameters to a named route is completely different from what you usually see. You need to outline a params parameter within the context.goNamed() perform. Right here’s the right way to arrange navigation to SettingsPage from HomePage with a route parameter.

baby: ElevatedButton(
  onPressed: () => context.goNamed(
    "settings",
     params: {"title": "codemagic"},
     ),
  baby: const Textual content("Go to Settings web page"),
),

Passing question parameters in go_router

You’ve got entry to queryParams within the context.goNamed() perform. The perfect factor about queryParams is that you just don’t must explicitly outline them in your route path and may simply entry them utilizing the state.queryParams technique. You’ll be able to add miscellaneous user-related knowledge as a question parameter.

Let’s take a look at an instance for example this idea. Within the ElevatedButton in HomePage, let’s add some question parameters to the settings route.

baby: ElevatedButton(
  onPressed: () => context.goNamed("settings", params: {
    "title": "codemagic"
  }, queryParams: {
    "e-mail": "[email protected]",
    "age": "25",
    "place": "India"
    }),
    baby: const Textual content("Go to Settings web page"),
),

Now we will entry these question parameters contained in the GoRouter configurations and move them to the web page. On this instance, I’m simply printing out the values for demonstration.

GoRoute(
  title: "settings",
  path: "settings/:title",
  builder: (context, state) {
    state.queryParams.forEach(
      (key, worth) {
        print("$key:$worth");
       },
     );
   return SettingsPage(
     title: state.params["name"]!,
   );
 },
)

Now, if you click on the button to navigate to the SettingsPage, you’ll be able to see the next output on the console display screen.

Dealing with 404 errors with go_router

When a person visits a display screen that’s not outlined within the GoRouter configuration, it causes an exception. However go_router supplies a very simple approach to deal with these errors, and you’ll present a customized web page to indicate to the person when this sort of exception happens.

We are able to outline an errorBuilder argument within the GoRouter object to deal with these 404 errors. Let’s make an ErrorScreen web page that features a button to navigate again to the HomePage.

class ErrorScreen extends StatelessWidget {
  const ErrorScreen({tremendous.key});

  @override
  Widget construct(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        automaticallyImplyLeading: true,
        title: const Textual content("Error Display screen"),
      ),
      physique: Middle(
        baby: ElevatedButton(
          onPressed: () => context.go("/"),
          baby: const Textual content("Go to dwelling web page"),
        ),
      ),
    );
  }
}

Now add this ErrorScreen to the errorBuilder argument of the GoRouter object.

remaining GoRouter _router = GoRouter(
  errorBuilder: (context, state) => const ErrorScreen(),
);

That’s it. Attempt to launch your Flutter app within the Chrome browser and navigate to a random path. You will note that ErrorScreen will seem as a response.

Redirecting routes utilizing go_router

Generally, you wish to programmatically navigate your person from one web page to a different primarily based on sure logic. You’ll be able to allow that function utilizing redirects in go_router. You’ll be able to outline a redirect for each path and a worldwide redirect for all pages.

For instance, when a brand new person opens your software, you’ll be able to navigate them to the login display screen as a substitute of the house display screen. Equally, when a logged-in person opens your software, you’ll be able to navigate them to the house web page. You’ll be able to implement this sort of function very simply utilizing go_router.

Let’s see the right way to implement a redirect in your app. Contained in the route, outline a redirect argument. Contained in the redirect builder, examine if the person is logged in or not. If they don’t seem to be logged in, navigate them to the /login web page. In any other case, present them the house web page.

remaining GoRouter _router = GoRouter(
  routes: [
    GoRoute(
      name: "home",
      path: "/",
      builder: (context, state) => const HomePage(),
      redirect: (context, state) {
        if (userIsNotLoggedIn){
          return "/login"
        }
        return "/"
      },
    ),
  ],
  errorBuilder: (context, state) => const ErrorScreen(),
);

GoRouter navigation comparability: go vs. push

GoRouter has two strategies for navigating between pages: GoRouter.of(context).go() and GoRouter.of(context).push(). On the floor, they give the impression of being very related, however they perform in another way. The push() technique stacks one web page on one other in navigation, whereas the go() technique straight navigates from one path to a different with none stacking.

Right here’s an instance to reveal this idea. Assume you have got three pages: A, B, and C. When you navigate from A to B to C utilizing the push technique, then C is stacked on high of B on high of A. Check out this diagram to know higher.

Then again, in case you navigate from A to B to C utilizing the go technique, then C is simply stacked on high of A and provided that A is the house web page with the route /. B is eradicated from the navigation stack altogether. Subsequently, the go() technique leaves no routing historical past.

You’ll be able to select which technique works greatest to your apps.

Bonus: Take away the # prefix from the online URL in Flutter

When you launch your app on the internet, you’ll be able to see a trailing # within the URL. Generally it appears very annoying, and you could wish to take away it. You’ll be able to simply obtain this with the assistance of a bundle known as url_strategy.

First, set up this bundle in your Flutter venture.

flutter pub add url_strategy

Then import this bundle in your most important.dart file, and add the setPathUrlStrategy() perform earlier than the runApp() perform.

Now, run your software. You’ll be able to see that the trailing # is faraway from the URL of your Flutter app.

Selecting between go_router, Navigator 2.0, and Beamer for navigation in Flutter

Flutter has a number of packages you should use for routing. Probably the most well-known ones are go_router, Navigator, and Beamer. How do you select which navigation to make use of to your app?

In case you are primarily focusing on cell platforms (Android and iOS) and don’t have time to study a brand new bundle for routing, it’s fully advantageous to make use of Navigator 1.0. It’s able to assembly all of your routing wants in Android/iOS apps.

Flutter’s core energy is in its multiplatform assist, which spans past simply Android and iOS. If you wish to make an actual multiplatform app that helps desktop and net platforms along with Android/iOS, then you need to migrate to Navigator 2.0. Navigator 2.0 supplies a really versatile and absolutely customizable routing answer for actually multiplatform apps.

However an enormous chunk of builders don’t just like the verbose nature of Navigator 2.0, which often requires you to jot down boilerplate code to create a easy route. If you wish to keep away from these points, you should use go_router, which is declarative and a considerably easier answer for Flutter. If in case you have a medium-sized to giant software and wish to deal with dynamic routes, go_router will help you reduce your effort and maximize the outcomes.

Beamer is the brand new child on the Flutter navigation stack. Like go_router, Beamer can be primarily based on the Flutter router API. It makes builders’ lives simpler by simplifying Navigator 2.0. In case you are already utilizing go_router, then there isn’t a want to modify to Beamer until you’re lacking some options and Beamer can fulfill your wants.

In case you are a newbie Flutter dev, you’ll be able to go along with both go_router or Beamer. Each are good and concentrate on developer productiveness by eradicating complexity and boilerplate code.

Construct your Flutter app utilizing Codemagic

Our app isn’t fully prepared for launch at this level, however let’s arrange a CI/CD pipeline for it anyway. Ideally, you need to do that proper from the beginning of the event course of to make it simpler to collaborate on the app with different builders and ship new options to testers and clients whereas avoiding falling into the “it really works on my laptop” entice.

Codemagic is a CI/CD platform for Flutter functions. You’ll be able to set off a brand new Flutter construct if you push your code to your GitHub/GitLab/Bitbucket repository. Then simply obtain the generated artifacts from the Codemagic dashboard and run them in your units (until you wish to publish them to shops, which Codemagic also can enable you with). Let’s see step-by-step the right way to arrange a CI/CD pipeline with Codemagic to your Flutter software.

In case you aren’t a Codemagic person but, you’ll be able to enroll right here:

Enroll

  1. Create a brand new Codemagic venture and join your repository.

  1. Choose Flutter because the venture sort.

  1. Below Automated construct triggering, examine Set off on push.

  1. Within the Construct tab, choose your Flutter model, construct format, and customized construct arguments.

  1. Click on on the Begin new construct button to provoke the primary construct of your software.

  2. After the construct completes, you’ll be able to obtain the artifacts and run the app in your units.

Conclusion

go_router is a really minimalistic however highly effective routing bundle for Flutter. It removes all of the complexity that Flutter Navigator 2.0 brings to the desk and supplies a really developer-friendly API to work with.

On this article, we’ve got mentioned the right way to use go_router in your Flutter app in addition to a few of its options, like route parameters, question parameters, named routes, dealing with errors, and redirection. That is only a newbie’s information for getting began with go_router. If you wish to study extra, go to the official go_router API documentation.

If in case you have any questions, you’ll be able to ask me on Twitter. Have day.

You will discover the pattern app on GitHub.


Hrishikesh Pathak is a Flutter developer and author. He likes to discover new know-how and write about it. Take a look at his posts on Codemagic’s weblog and his private weblog.



Related Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Latest Articles