Route paths are defined and implemented in the path_to_regexp package, which gives you the ability to include parameters in your route's path:

final _router = GoRouter(
  routes: [
      path: '/family/:fid',
      builder: (context, state) {
        // use state.params to get router parameter values
        final family = Families.family(state.params['fid']!);
        return FamilyScreen(family: family);

You can access the matched parameters in the state object using the params property.

Dynamic Linking#

The idea of "dynamic linking" is that as the user adds objects to your app, each of them gets a link of their own, e.g. a new family gets a new link. This is exactly what route parameters enables, e.g. a new family has its own identifier when can be a variable in your family route, e.g. path: /family/:fid.

Query Parameters#

Including parameters in the path is one way to pass information to the page. A "path" parameter is required and inline with the location. The other way to pass data as part of a location is to use query parameters, which is a set of name-value pairs passed at the end of a URI after a ? character, e.g.

void _tap() => context.go('/search?query=kitties');

These parameters are optional and, if passed, will be provided in the state.queryParams property for every page matched in a stack of routes:

  path: '/search',
  builder: (context, state) {
    // use state.queryParams to get search query from query parameter
    final query = state.queryParams['query']; // may be null
    return SearchPage(query: query);

Since query parameters are optional, they will be null if they're not passed.

Extra Parameter#

In addition to passing along path and query parameters, you can also pass along an extra object as part of your navigation, e.g.

void _tap() => context.go('/family', extra: _family);

This object is provided as state.extra:

  path: '/family',
  builder: (context, state) => FamilyScreen(family: state.extra! as Family),

The extra object is useful if you'd like to simply pass along a single object to the builder function w/o passing an object identifier via a URI and looking up the object from a store. Also, if the user presses the Back button on an AppBar, the extra object will be passed along properly.

However, the extra object cannot be used to create a dynamic link nor can it be used in deep linking. Furthermore, since a press of the brower's Back button is treated like a deep link for purposes of navigation, the extra object will be lost when the user navigates back via the browser. For these reasons, the use of the extra object is not recommended for use in targeting Flutter web apps.