There are many ways to navigate between destinations in your app.
Navigating to a destination in GoRouter will replace the current stack of screens with the screens configured to be displayed for the destination route. To change to a new screen, call context.go()
with a URL:
build(BuildContext context) { return TextButton( onPressed: () => context.go('/users/123'), ); }
This is shorthand for calling GoRouter.of(context).go('/users/123)
.
To build a URI with query parameters, you can use the Uri
class from the Dart standard library:
context.go(Uri(path: '/users/123', queryParameters: {'filter': 'abc'}).toString());
GoRouter can push a screen onto the Navigator's history stack using context.push()
, and can pop the current screen via context.pop()
. However, imperative navigation is known to cause issues with the browser history.
To learn more, see issue #99112.
You can use a Link widget from the url_launcher package to create a link to destinations in your app. This is equivalent to calling context.go()
, but renders a real link on the web.
To add a Link to your app, follow the Link API documentation from the url_launcher package.
You can also use Named routes to navigate instead of using URLs.
GoRouter and other Router-based APIs are not compatible with the WillPopScope widget.
See issue #102408 for details on what such an API might look like in go_router.
You can continue using the Navigator to push and pop pages. Pages displayed in this way are not deep-linkable and will be replaced if any parent page that is associated with a GoRoute is removed, for example when a new call to go()
occurs.
To push a screen using the imperative Navigator API, call NavigatorState.push()
:
Navigator.of(context).push( MaterialPageRoute( builder: (BuildContext context) { return const DetailsScreen(); }, ), );
Waiting for a value to be returned:
onTap: () { final bool? result = await context.push<bool>('/page2'); if(result ?? false)... }
Returning a value:
onTap: () => context.pop(true)
You can provide additional data along with navigation.
context.go('/123, extra: 'abc');
and retrieve the data from GoRouterState
final String extraString = GoRouterState.of(context).extra! as String;
The extra data will go through serialization when it is stored in the browser. If you plan to use complex data as extra, consider also providing a codec to GoRouter so that it won't get dropped during serialization.
For an example on how to use complex data in extra with a codec, see extra_codec.dart.