Skip to Content

Navigation

It’s go_router underneath, so the standard BuildContext navigation methods work as you expect. On top of that, go_router_modular adds async variants that wait for the destination module’s dependencies to finish registering.

Standard navigation

context.go('/home'); // replace the stack context.push('/details'); // push on top context.pop(); // pop the current route context.replace('/settings'); // replace the current route context.goNamed( 'user', pathParameters: {'id': '42'}, queryParameters: {'tab': 'posts'}, );

Async navigation

The async variants return a Future that completes only after the destination module’s binds have registered and the new page is built. Each takes an optional extra payload and an onComplete callback.

await context.goAsync('/dashboard'); await context.goNamedAsync( 'user', pathParameters: {'id': '42'}, queryParameters: {'tab': 'posts'}, onComplete: () => print('dependencies ready'), );

The same shapes exist for every navigation verb:

  • goAsync / goNamedAsync
  • pushAsync / pushNamedAsync
  • pushReplacementAsync / pushReplacementNamedAsync
  • replaceAsync / replaceNamedAsync

Signatures:

Future<void> goAsync(String route, {Object? extra, VoidCallback? onComplete}); Future<void> goNamedAsync( String name, { Map<String, String> pathParameters = const {}, Map<String, String> queryParameters = const {}, Object? extra, VoidCallback? onComplete, });

Prefer goAsync over go when you need to run code right after the destination’s dependencies are ready — for example, reading a controller the destination module registers, or awaiting navigation in a flow. For plain navigation, go is fine.

Popping to a location

context.popUntil('/home'); // pop until this location is on top context.popUntilNamed('home'); // pop until this named route is on top

Reading route state

Use the Modular facade to read the current route state from a BuildContext. The methods follow the ...Of(context) convention:

final state = Modular.routerStateOf(context); // the GoRouterState final path = Modular.currentPathOf(context); // current path final id = Modular.pathParamOf(context, 'id'); // a path parameter final params = Modular.pathParamsOf(context); // all path parameters final ref = Modular.queryParamOf(context, 'ref'); // a query parameter final queries = Modular.queryParamsOf(context); // all query parameters final uri = Modular.currentUriOf(context); // current Uri final location = Modular.currentLocationOf(context); // current location final payload = Modular.extraOf<MyPayload>(context); // typed extra

The extension shortcuts context.getPathParam('id'), context.getPath and context.state still work, but are deprecated in favor of Modular.pathParamOf, currentPathOf and routerStateOf. They will be removed in a future major release.

You can also use the go_router utilities directly (GoRouterState, context.go, context.push, …) — they are re-exported by the package barrel, so importing package:go_router_modular/go_router_modular.dart is enough.

Dependency lookup

Resolve a registered dependency from a widget with context.read<T>():

final controller = context.read<HomeController>();

modularNavigatorKey is a GlobalKey<NavigatorState> that gives you the current navigator context anywhere — services, interceptors, background callbacks.

final context = modularNavigatorKey.currentContext; context?.go('/login');

On the web

Deep links, the URL bar, and browser back/forward all work — it’s go_router under the hood, so path and query parameters round-trip through the URL.

Next steps

Last updated on