AgentSkillsCN

routing

在使用`go_router`添加页面、深度链接或复杂导航流程时使用此功能。

SKILL.md
--- frontmatter
name: routing
description: When adding screens, deep links, or complex navigation flows using `go_router`.

Routing (GoRouter)

When to use

  • Adding a new screen or feature entry point.
  • Implementing deep linking or redirection (e.g., AuthGuard).
  • Passing arguments between screens.

Setup

Define a centralized local_router.dart (or similar) in core/router/ or app/router/. Prefer nested/sub-routes over a flat list so deep links and back navigation remain predictable.

dart
final goRouter = GoRouter(
  initialLocation: '/',
  debugLogDiagnostics: true,
  routes: [
    GoRoute(
      path: '/',
      builder: (context, state) => const HomePage(),
      routes: [
        GoRoute(
          path: 'details/:id',
          builder: (context, state) {
            final id = state.pathParameters['id']!;
            return DetailPage(id: id);
          },
        ),
      ],
    ),
  ],
);

Best Practices

1) Type-Safe Arguments

  • Use path parameters for IDs (e.g. details/:id).
  • Use query parameters for filtering/sorting state (for example: ?status=paid&page=2).
  • Use extra for complex objects only if necessary. Prefer passing an ID and refetching data to ensure the screen is independent and deep-linkable.
  • Prefer typed routes or goNamed over raw path strings where possible.
  • Keep route path segments lowercase kebab-case (for example user/update-address).

2) Redirects (Guards)

  • implement redirect logic at the top level or per-route.
dart
redirect: (context, state) {
  final isLoggedIn = authBloc.state.isAuthenticated;
  final isLoggingIn = state.uri.path == '/login';

  if (!isLoggedIn && !isLoggingIn) return '/login';
  if (isLoggedIn && isLoggingIn) return '/';

  return null;
},

3) Navigation

  • Use context.go('/details/123') or context.goNamed(...) for normal app/deep-linkable navigation.
  • Use context.push('/details/123') when the route is transient and should return a result on pop.
  • Prefer BuildContext extensions (context.goNamed, context.pushNamed) over GoRouter.of(context) for consistency.