go_router

Migrating to 2.5

go_router v2.5 comes with a new, simplified way to provide a screen for each route in your app. In versions prior to v2.5, the only way to do that was to implement the pageBuilder function for each route, e.g.

GoRoute(
  path: '/',
  pageBuilder: (context, state) => MaterialPage<void>( // boilerplate
    key: state.pageKey, // boilerplate
    restorationId: state.pageKey.value, // boilerplate
    child: const Page1Page(), // useful code
  ), // boilerplate
),

This method came with a lot of boilerplate code if you were using the default transitions provided with the MaterialApp (or CupertinoApp) since you were forced to build up a MaterialPage (or CupertinoPage) for every route. Furthermore, assuming you wanted to let go_router pick the key for each of your pages instead of managing that yourself, you still had to manually pass the key to each MaterialPage instance (or CupertinoPage instance). And finally, you had to pass in a restorationId value by hand as well.

builder instead of pageBuilder#

In v2.5, if you want to let go_router pick the appropriate page-type based on your app-type, i.e. MaterialApp, CupertinoApp or something else, and you want to let go_router manage the keys and restoration IDs, you can use the default implementation of the pageBuilder for each route and instead implement the builder function:

GoRoute(
  path: '/',
  builder: (context, state) => const Page1Page(),  // just the useful code!
),

This code removes the boilerplate and gives you the default implementation of the pageBuilder that you expect (in fact, it looks just like the pageBuilder snippet above). You can continue to use the pageBuilder if you want to specify the key or some other parameter to the page-type you're creating:

GoRoute(
  path: '/',
  pageBuilder: (context, state) => MaterialPage<void>(
    key: _myPage1Key,
    child: const Page1Screen(),
  ),
),

Likewise, if you want to set a custom transition, you can still use the pageBuilder for that, too:

GoRoute(
  path: '/fade',
  pageBuilder: (context, state) => CustomTransitionPage<void>(
    key: state.pageKey,
    child: const ExampleTransitionsScreen(
      kind: 'fade',
      color: Colors.red,
    ),
    transitionsBuilder: (context, animation, secondaryAnimation, child) =>
        FadeTransition(opacity: animation, child: child),
  ),
),

However, I expect most people to use builder instead of pageBuilder most of the time.

Optional error builder#

Another simplification in go_router v2.5 is that you're no longer required to provide an errorPageBuilder function. Instead, go_router will automatically give you a simple one based on the app-type you're using, e.g. MaterialApp, CupertinoApp or something else. Of course, if you want a custom error screen, you can continue to use errorPageBuilder or take advantage of the new errorBuilder function instead:

final _router = GoRouter(
  routes: ...,
  errorBuilder: (context, state) => ErrorScreen(state.error!),
);

The errorBuilder takes advantage of the new default implementation of the errorPageBuilder function that works just like the pageBuilder, although you're free to use either.

No transition at all#

And finally, if you'd like to remove the transition from a route, there's a new NoTransitionPage type that derives from the existing CustomTransitionPage to handle the case of turning off transitions:

GoRoute(
  path: '/none',
  pageBuilder: (context, state) => NoTransitionPage<void>(
    key: state.pageKey,
    child: const ExampleTransitionsScreen(
      kind: 'none',
      color: Colors.white,
    ),
  ),
),

In fact, the NoTransitionPage is what you'll get in the case that your app doesn't have a MaterialApp or a CupertinoApp in the widget tree, e.g. if you're using WidgetsApp. You can read more about custom transitions for details.