Files

62 lines
2.0 KiB
Cheetah

---
description: "GoRouter conventions for {{PROJECT_NAME}}"
alwaysApply: true
---
# GoRouter Standards — {{PROJECT_NAME}}
## Typed routes (mandatory)
```dart
// Define typed routes — never use string paths directly in navigation calls
@TypedGoRoute<HomeRoute>(path: '/')
class HomeRoute extends GoRouteData {
const HomeRoute();
@override Widget build(BuildContext ctx, GoRouterState state) => const HomeScreen();
}
@TypedGoRoute<ProductRoute>(path: '/products/:id')
class ProductRoute extends GoRouteData {
final String id;
const ProductRoute({required this.id});
@override Widget build(BuildContext ctx, GoRouterState state) => ProductScreen(id: id);
}
// Navigate with type safety
const ProductRoute(id: product.id).go(context); // ✅
context.go('/products/${product.id}'); // ❌ — don't do this
```
## Auth guard
```dart
// Redirect logic in router config
redirect: (context, state) {
final isLoggedIn = ref.read(authProvider).isAuthenticated;
final isLoginRoute = state.matchedLocation == '/login';
if (!isLoggedIn && !isLoginRoute) return '/login';
if (isLoggedIn && isLoginRoute) return '/';
return null;
},
```
## Shell routes for bottom navigation
```dart
ShellRoute(
builder: (ctx, state, child) => MainScaffold(child: child),
routes: [
GoRoute(path: '/home', builder: (_, __) => const HomeScreen()),
GoRoute(path: '/search', builder: (_, __) => const SearchScreen()),
GoRoute(path: '/profile', builder: (_, __) => const ProfileScreen()),
],
)
```
## Deep links
- Register URL schemes in `Info.plist` (iOS) and `AndroidManifest.xml`
- Test deep links with: `adb shell am start -a android.intent.action.VIEW -d "app://{{PACKAGE_ID}}/products/123"`
- Handle `GoRouter.of(context).routerDelegate.currentConfiguration` for dynamic links
## Rules
- **NEVER** use `Navigator.push/pop` — use `context.go()`, `context.push()`, `context.pop()`
- All routes declared in one file: `lib/core/routing/app_router.dart`
- `BlocProvider`s for route-level blocs created inside the `builder` of each route