vgv-navigation

Par verygoodopensource · vgv-ai-flutter-plugin

Bonnes pratiques pour la navigation et le routage dans Flutter avec GoRouter.

npx skills add https://github.com/verygoodopensource/vgv-ai-flutter-plugin --skill vgv-navigation

Navigation

Bonnes pratiques de routage et navigation pour les applications Flutter utilisant GoRouter, le package de routage recommandé par l'équipe Flutter basé sur l'API Navigator 2.0.

Core Standards

Appliquez ces standards à TOUS les travaux de navigation :

  • Utilisez package:go_router pour toute navigation — jamais le Navigator 2.0 brut ou les push/pop du Navigator 1.0
  • Utilisez les annotations @TypedGoRoute pour des routes type-safe — jamais les chemins bruts en chaîne de caractères dans les définitions de routes
  • Préférez go() à push() — utilisez push() seulement si vous attendez des données de retour de la destination
  • N'utilisez jamais le paramètre extra — cela casse le deep linking et ne fonctionne pas sur le web
  • Routes hiérarchiques imbriquées pour une navigation arrière correcte — structurez les routes comme des arbres parent-enfant, pas des listes plates
  • Tirets pour la séparation de mots dans les URL — jamais de traits de soulignement ou camelCase dans les chemins URL
  • Naviguez par nom de route, pas par chaînes de chemin brutes — utilisez la navigation par nom de route pour découpler les changements de chemin
  • Utilisez les extensions BuildContext pour la navigation — préférez context.goNamed() à GoRouter.of(context).goNamed()

Route Organization

Structurez les routes de manière hiérarchique avec des relations logiques parent-enfant. Les sous-routes garantissent que le bouton retour de la barre d'application s'affiche correctement et que les URLs restent propres.

Hierarchical Structure (Preferred)

/flutter
  /flutter/news
  /flutter/chat
  /flutter/articles
    /flutter/articles?category=all
    /flutter/article/:id
/android
  /android/news
  /android/chat

Flat Structure (Avoid)

/flutter-news
/flutter-chat
/android-news
/android-chat

Les sous-routes hiérarchiques produisent une navigation arrière correcte automatiquement — quand un utilisateur est sur /flutter/news, le bouton retour navigue vers /flutter.

Type-Safe Routes

Utilisez les annotations @TypedGoRoute avec les classes GoRouteData pour éliminer les fautes de frappe et les conversions de paramètres manuelles. Le package go_router_builder génère des assistants de route type-safe à la compilation.

Basic Route

@TypedGoRoute<CategoriesPageRoute>(
  name: 'categories',
  path: '/categories',
)
@immutable
class CategoriesPageRoute extends GoRouteData {
  const CategoriesPageRoute({
    this.size,
    this.color,
  });

  final String? size;
  final String? color;

  @override
  Widget build(BuildContext context, GoRouterState state) {
    return CategoriesPage(size: size, color: color);
  }
}

Route with Sub-Routes

@TypedGoRoute<FlutterPageRoute>(
  name: 'flutter',
  path: '/flutter',
  routes: [
    TypedGoRoute<FlutterNewsPageRoute>(
      name: 'flutterNews',
      path: 'news',
    ),
    TypedGoRoute<FlutterArticlesPageRoute>(
      name: 'flutterArticles',
      path: 'articles',
      routes: [
        TypedGoRoute<FlutterArticlePageRoute>(
          name: 'flutterArticle',
          path: 'article/:id',
        ),
      ],
    ),
  ],
)
@immutable
class FlutterPageRoute extends GoRouteData {
  const FlutterPageRoute();

  @override
  Widget build(BuildContext context, GoRouterState state) {
    return const FlutterPage();
  }
}

Navigation Methods

go() vs push()

Method URL Updates Back Button Use Case
go() Yes App bar Standard navigation between screens
push() No System When expecting return data from popped route

Using go() (Default)

const CategoriesPageRoute(size: 'small', color: 'blue').go(context);

L'utilisation de go() garantit que le bouton retour dans l'AppBar de l'application s'affiche quand la route actuelle a un parent vers lequel naviguer.

Using push() (Return Data Only)

final result = await DialogPageRoute().push<String>(context);

Utilisez push() seulement quand une route doit retourner des données (par exemple, une dialog collectant l'entrée utilisateur). Sur le web, push() ne met pas à jour la barre d'adresse.

BuildContext Extensions

Utilisez toujours les méthodes d'extension pour une syntaxe plus propre :

// Preferred
context.goNamed('flutterNews');

// Avoid
GoRouter.of(context).goNamed('flutterNews');

Parameter Strategies

Utilisez les paramètres de chemin (:id) pour l'identification de ressource et les paramètres de requête (?category=all) pour le filtrage optionnel. N'utilisez jamais extra — cela casse le deep linking et ne fonctionne pas sur le web.

Voir references/parameters.md pour des exemples complets de paramètres de chemin, paramètres de requête, et pourquoi extra est interdit.

Redirects

Les redirects peuvent être appliqués au niveau du routeur racine (par exemple, les garde d'authentification) et au niveau des routes individuelles (par exemple, les garde d'autorisation). Les redirects parents s'exécutent avant les redirects enfants.

Voir references/redirects.md pour des exemples de redirects au niveau racine et au niveau des routes.

Testing

Simulez GoRouter avec package:mocktail et enveloppez les widgets dans InheritedGoRouter pour les tests de widgets. Testez les redirects en construisant un GoRouter avec la logique de redirect cible et en affirmant la page résultante.

Voir references/testing.md pour des exemples de simulation de GoRouter et de test de redirects.

Common Patterns

Adding a New Route

  1. Créez le widget page (en suivant le pattern Page/View si vous utilisez Bloc)
  2. Définissez une classe GoRouteData avec l'annotation @TypedGoRoute
  3. Ajoutez-la comme sous-route sous la route parent appropriée
  4. Exécutez dart run build_runner build --delete-conflicting-outputs pour régénérer les assistants de route
  5. Naviguez en utilisant la classe de route type-safe générée

Deep Linking Setup

  1. Structurez les routes de manière hiérarchique avec des chemins URL significatifs
  2. Utilisez les paramètres de chemin pour l'identification de ressource
  3. Utilisez les paramètres de requête pour le filtrage — jamais extra
  4. Naviguez par nom de route afin que la restructuration de chemin ne casse pas les liens
  5. Testez les deep links en lançant l'application avec l'URL cible

Nested Navigation (Shell Routes)

@TypedShellRoute<AppShellRoute>(
  routes: [
    TypedGoRoute<HomePageRoute>(
      name: 'home',
      path: '/home',
    ),
    TypedGoRoute<SettingsPageRoute>(
      name: 'settings',
      path: '/settings',
    ),
  ],
)
class AppShellRoute extends ShellRouteData {
  @override
  Widget builder(BuildContext context, GoRouterState state, Widget navigator) {
    return AppShell(child: navigator);
  }
}

Quick Reference

Package Purpose
go_router Declarative routing built on Navigator 2.0
go_router_builder Code generation for type-safe route classes
Command Purpose
dart run build_runner build --delete-conflicting-outputs Generate type-safe route helpers
dart run build_runner watch --delete-conflicting-outputs Watch and regenerate on changes

Skills similaires