flutterdartflutter-go-router

Why is GoRouter complaining I'm using a parameterized route as a default location when I'm not?


GoRouter is complaining that I'm using a parameterized route as the default location, but I'm not.

The default location of a StatefulShellBranch cannot be a parameterized route
'package:go_router/src/configuration.dart':
Failed assertion: line 148 pos 17: 'route!.pathParameters.isEmpty'

My route definition:

final router = GoRouter(
  initialLocation: '/recipe',
  routes: <RouteBase>[
    StatefulShellRoute.indexedStack(
      builder: (context, state, navigationShell) {
        return MainScreen(navigationShell);
      },
      branches: [
        StatefulShellBranch(
          routes: [
            GoRoute(
              path: '/recipe',
              builder: (context, state) => RecipeListView(),
            ),
          ],
        ),
        StatefulShellBranch(
          routes: [
            GoRoute(
              path: '/recipe/:recipe',
              builder: (context, state) => RecipeView(),
            ),
          ],
        ),
      ],
    ),
  ],
);

How can I fix this?


Solution

  • I think the issue is that GoRouter is interpreting the second branch's route (/recipe/:recipe) as the default location for that branch, and parameterised routes cannot be used as default locations for StatefulShellBranch.

    The happens because each StatefulShellBranch needs a non-param route as its first route to serve as the default. Here's how I reckon you could fix it by adding a default route to the second branch:

    Assuming your nav is hierarchical I think nested routes might be the way to go:

    final router = GoRouter(
      initialLocation: '/recipe',
      routes: <RouteBase>[
        StatefulShellRoute.indexedStack(
          builder: (context, state, navigationShell) {
            return MainScreen(navigationShell);
          },
          branches: [
            StatefulShellBranch(
              routes: [
                GoRoute(
                  path: '/recipe',
                  builder: (context, state) => RecipeListView(),
                  routes: [
                    GoRoute(
                      path: ':recipe',  // This becomes /recipe/:recipe
                      builder: (context, state) {
                        final recipeName = state.pathParameters['recipe']!;
                        return RecipeView(recipeName: recipeName);
                      },
                    ),
                  ],
                ),
              ],
            ),
            // Add other branches as needed
          ],
        ),
      ],
    );