Auto Route
Annotation-based route generation for GoRouter. Annotate widgets with @PageRoute() to automatically generate route definitions.
Features
- 🚀 Zero boilerplate - Just add
@PageRoute()to your widget class - 📍 Auto-generated paths - Converts
FarmerRegistrationPageto/farmer-registration - 🏷️ Auto-generated names - Converts
FarmerRegistrationPagetoFarmerRegistration - 🔗 Path parameters - Support for
:idand other path params - 📦 Bloc integration - Automatic
BlocProviderwrapping - 🎯 Type-safe extras - Generic type parameter for props (
@PageRoute<MyProps>()) - 🐚 Shell routes - Group pages under navigation shells
- ⚡ Custom transitions - Support for fade, slide, and no-transition pages
Package Structure
This package consists of two parts:
| Package | Description | Dependency Type |
|---|---|---|
auto_go_router |
Annotations and models | dependencies |
auto_go_router_generator |
Code generator | dev_dependencies |
Note: Both packages are published separately on pub.dev but maintained in a single repository (monorepo pattern). This is the same approach used by popular packages like
freezed/freezed_annotationandjson_serializable/json_annotation.
Installation
Add both packages to your pubspec.yaml:
dependencies:
flutter:
sdk: flutter
go_router: ^14.0.0
auto_go_router: ^0.0.1
dev_dependencies:
build_runner: ^2.4.0
auto_go_router_generator: ^0.0.1
Then run:
flutter pub get
Usage
1. Annotate your pages
import 'package:auto_go_router/auto_go_router.dart';
import 'package:flutter/material.dart';
// Simple page - auto-generated path and name
@PageRoute()
class SettingsPage extends StatelessWidget {
const SettingsPage({super.key});
// ...
}
// Generated: path: '/settings', name: 'Settings'
2. Run the generator
dart run build_runner build
3. Use the generated routes
import 'routes.auto_go_router.g.dart';
final router = GoRouter(
initialLocation: $AppPages.home.routePath,
routes: $autoRoutes,
);
Annotation Options
Basic Usage
@PageRoute()
class SettingsPage extends StatelessWidget {}
// → path: '/settings', name: 'Settings'
Initial Route
@PageRoute(isInitial: true)
class HomePage extends StatelessWidget {}
// → Will be first in the routes list
Custom Path and Name
@PageRoute(
path: '/api/v1/products',
name: 'ProductList',
)
class ProductListPage extends StatelessWidget {}
Path Parameters
@PageRoute(
pathParams: ['id'],
pathParamMappings: {'id': 'userId'},
)
class ProfilePage extends StatelessWidget {
final String userId;
const ProfilePage({required this.userId, super.key});
}
// → path: '/profile/:id'
// → Generated code extracts state.pathParameters['id'] to userId
Type-Safe Extras (Recommended)
Use the generic type parameter for type-safe props:
class UserDetailsPageProps {
final String userName;
final String email;
const UserDetailsPageProps({required this.userName, required this.email});
}
@PageRoute<UserDetailsPageProps>()
class UserDetailsPage extends StatelessWidget {
final UserDetailsPageProps props;
const UserDetailsPage({required this.props, super.key});
}
// → Generated code casts state.extra to UserDetailsPageProps
Bloc Provider Wrapper
@PageRoute(wrapWithBloc: 'CounterBloc')
class CounterPage extends StatelessWidget {}
// → Wrapped with BlocProvider<CounterBloc>
// With ServiceLocator
@PageRoute(
wrapWithBloc: 'CounterBloc',
useServiceLocator: true,
)
class CounterPage extends StatelessWidget {}
// → create: (_) => ServiceLocator.getIt<CounterBloc>()
Page Transitions
// No transition
@PageRoute(transition: PageTransitionType.none)
class SplashPage extends StatelessWidget {}
// Fade transition
@PageRoute(transition: PageTransitionType.fade)
class FadePage extends StatelessWidget {}
// Slide from right
@PageRoute(transition: PageTransitionType.slideRight)
class SlidePage extends StatelessWidget {}
// Slide from bottom
@PageRoute(transition: PageTransitionType.slideBottom)
class ModalPage extends StatelessWidget {}
Shell Route Groups
@PageRoute(shellGroup: 'mainNav')
class HomePage extends StatelessWidget {}
@PageRoute(shellGroup: 'mainNav')
class ProfilePage extends StatelessWidget {}
// → Both pages grouped under the same ShellRoute
Generated Output
The generator creates a routes.auto_go_router.g.dart file with:
// Auto-generated enum
enum $AppPages {
home,
settings,
profile,
// ...
}
// Extension for path and name
extension $AppPagesExtension on $AppPages {
String get routePath { ... }
String get routeName { ... }
String routePathWithId(String id) { ... }
}
// Generated routes list
final List<RouteBase> $autoRoutes = [
GoRoute(
path: $AppPages.home.routePath,
name: $AppPages.home.routeName,
builder: (context, state) => const HomePage(),
),
// ...
];
Migration Strategy
You can gradually migrate existing routes:
final router = GoRouter(
routes: [
...manualRoutes, // Your existing routes
...$autoRoutes, // Generated routes
],
);
Configuration (build.yaml)
Create a build.yaml file in your project root to configure the generator:
targets:
$default:
builders:
auto_go_router_generator|auto_go_router_scanner:
enabled: true
generate_for:
- lib/**/*.dart
auto_go_router_generator|auto_go_router_aggregator:
enabled: true
Example
See the example directory for a complete Flutter app demonstrating all features.
cd example
flutter pub get
dart run build_runner build
flutter run
Publishing to pub.dev
For Package Maintainers
This repository uses a monorepo structure with two packages:
auto_go_router/
├── lib/ # auto_go_router package (annotations)
├── pubspec.yaml
├── auto_go_router_generator/ # auto_go_router_generator package (code gen)
│ ├── lib/
│ └── pubspec.yaml
└── example/ # Example Flutter app
To publish both packages:
# Publish auto_go_router first (it's a dependency of the generator)
cd /path/to/auto_go_router
dart pub publish
# Then publish the generator
cd auto_go_router_generator
dart pub publish
Version Compatibility
Always ensure both packages have compatible versions. The generator's pubspec.yaml should reference a specific version range of auto_go_router:
# In auto_go_router_generator/pubspec.yaml
dependencies:
auto_go_router: ^0.0.1 # Match the published version
Troubleshooting
Common Issues
1. Generated file not found
# Clean and rebuild
dart run build_runner clean
dart run build_runner build --delete-conflicting-outputs
2. Import conflicts with Flutter's PageRoute
// Hide Flutter's PageRoute when importing
import 'package:flutter/material.dart' hide PageRoute;
import 'package:auto_go_router/auto_go_router.dart';
3. Enum value naming The generator automatically sanitizes route names for valid Dart identifiers:
'HOME sweet'→homeSweet'User Profile'→userProfile'my-page_name'→myPageName
Contributing
Contributions are welcome! Please read our contributing guidelines before submitting PRs.
License
MIT License
Libraries
- auto_go_router
- Annotation-based route generation for GoRouter.