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)