auto_go_route 1.0.8
auto_go_route: ^1.0.8 copied to clipboard
A powerful, type-safe, and feature-rich routing package for Flutter GoRouter with automatic code generation.
Auto Go Route #
A powerful, type-safe, and feature-rich routing package for Flutter with automatic code generation. Built on top of GoRouter with enhanced developer experience and production-ready features.

Features #
✨ Type-Safe Navigation - Compile-time route validation and parameter checking
🔄 Automatic Code Generation - Zero boilerplate with @AutoGoRoute
annotations
📱 Flutter-First - Built specifically for Flutter with full widget integration
🎯 Parameter Auto-Detection - Automatically extract required/optional parameters from paths
📚 Documentation Generation - Auto-generate route documentation in multiple formats
🔍 Route Registry - Centralized route management with validation and analytics
⚡ Performance Monitoring - Built-in performance tracking and optimization
🛡️ Production Ready - Comprehensive error handling and validation
🐚 Shell Routes - Support for nested navigation with shell routes
🔗 Nested Routes - Hierarchical route structure with parent-child relationships
Installation #
Add the following to your pubspec.yaml
:
dependencies:
auto_go_route: ^1.0.8 # Use the latest version
go_router: ^16.0.0 # Match the version compatible with the package
dev_dependencies:
build_runner: ^2.4.15 # Match the version compatible with the package
auto_go_route_generator: ^1.0.8 # Use the latest version
Then run:
flutter pub get
Quick Start #
1. Annotate Your Page Widgets #
Add the @AutoGoRoute
annotation to any widget you want to make a screen.
import 'package:flutter/material.dart';
import 'package:auto_go_route/auto_go_route.dart';
@AutoGoRoute(path: '/login')
class LoginPage extends StatelessWidget {
const LoginPage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Login')),
body: const Center(child: Text('Login Page')),
);
}
}
2. Create a Central Router Class #
This class is the entry point for the generator.
// lib/app_router.dart
import 'package:auto_go_route/auto_go_route.dart';
part 'app_router.routes.g.dart'; // IMPORTANT: Use `.routes.g.dart`
@AutoGoRouteBase(initialLocation: '/home')
class AppRouter extends _$AppRouter {}
3. Generate Routes #
Run the build runner to generate the necessary code.
dart run build_runner build
4. Set Up and Use the Router #
Instantiate your AppRouter
and use the generated buildRouter()
method in your MaterialApp
.
// lib/main.dart
import 'package:flutter/material.dart';
import 'app_router.dart';
void main() {
runApp(const MyApp());
}
// Create an instance of your generated router
final appRouter = AppRouter();
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routerConfig: appRouter.buildRouter(),
);
}
}
5. Navigate with Type-Safety and Ease #
Use the generated BuildContext
extension for the shortest, safest, and most convenient navigation.
// Navigate to a simple route
context.goToLogin();
// Navigate to a route with path parameters, query parameters, and extra data
context.pushToUserProfile(
userId: 'user123',
queries: {'ref': 'email_campaign'},
extra: User(id: 'user123', name: 'John Doe'),
);
Advanced Usage #
Parameters and extra
Injection #
The generator automatically injects path/query parameters (simple types) and the extra
object (complex types) into your widget's constructor.
// The user object is passed as `extra`
@AutoGoRoute(path: '/user/:userId')
class UserProfilePage extends StatelessWidget {
final String userId; // From path
final String? tab; // From query (optional)
final User? user; // From `extra` object
const UserProfilePage({
super.key,
required this.userId,
this.tab,
this.user,
});
//...
}
// Navigation call
context.pushToUserProfile(
userId: '123',
queries: {'tab': 'settings'},
extra: User(id: '123', name: 'Jane Doe'),
);
Stateful Shell Routes (e.g., Bottom Navigation) #
Use @AutoGoRouteShell
with isStateful: true
. Use the order
property on children to define the order of the branches (and bottom navigation tabs).
@AutoGoRouteShell(
path: '/',
isStateful: true,
// Automatically redirects from '/' to the first child's path ('/home')
)
class DashboardShell extends StatelessWidget {
final StatefulNavigationShell navigationShell;
const DashboardShell({super.key, required this.navigationShell});
// ... build Scaffold with BottomNavigationBar using navigationShell ...
}
@AutoGoRoute(path: '/home', parent: DashboardShell, order: 0)
class HomePage extends StatelessWidget { /* ... */ }
@AutoGoRoute(path: '/profile', parent: DashboardShell, order: 1)
class ProfilePage extends StatelessWidget { /* ... */ }
Custom Page Transitions (Dialogs/Bottom Sheets) #
Use the pageBuilder
property on a non-stateful ShellRoute
to wrap its children in a custom Page
, like a dialog or bottom sheet.
1. Define your Page Builder function:
// lib/utils/adaptive_page_builder.dart
Page<dynamic> adaptiveOverlayPageBuilder(BuildContext context, GoRouterState state, Widget child) {
// Return your custom Page class, e.g., AdaptiveOverlayPage
return AdaptiveOverlayPage(
child: child,
barrierDismissible: false,
heightFactor: 0.9,
);
}
2. Use it in your annotation:
@AutoGoRouteShell(
path: '/my-dialog-flow',
pageBuilder: 'adaptiveOverlayPageBuilder', // Pass the function name as a string
)
class MyDialogShell extends StatelessWidget {
// This widget is a placeholder for the annotation
final Widget child;
const MyDialogShell({super.key, required this.child});
@override
Widget build(BuildContext context) => child;
}
@AutoGoRoute(path: '/step1', parent: MyDialogShell)
class DialogStep1 extends StatelessWidget { /* ... */ }
Middleware (Route Guards) #
Middleware functions intercept navigation to perform checks like authentication or feature flagging.
1. Create a Middleware Function #
The function must return null
to allow navigation or a String
path to redirect.
// lib/middleware/auth_middleware.dart
import 'dart:async';
import 'package:go_router/go_router.dart';
import 'package:flutter/material.dart';
FutureOr<String?> authMiddleware(BuildContext context, GoRouterState state) {
final isLoggedIn = ... // Your auth logic here
if (!isLoggedIn) {
return '/login'; // Redirect to login
}
return null; // Proceed
}
2. Apply Middleware to a Route #
Add the name of your middleware function (as a string) to the middleware
list in the annotation.
@AutoGoRoute(
path: '/profile',
middleware: ['authMiddleware'], // Apply the guard
)
class ProfilePage extends StatelessWidget { ... }
API Reference #
Annotations #
@AutoGoRoute
@AutoGoRoute({
required String path, // Route path with parameters
String? name, // Optional route name
String? description, // Description for documentation
List middleware = const [], // Middleware functions
Type? parent, // Parent route class for nesting
int? order, // Order of the route in the parent
})
@AutoGoRouteShell
@AutoGoRouteShell({
required String path, // Shell route path
String? name, // Optional shell name
String? description, // Description for documentation
String? navigatorKey, // Navigator key identifier
Type? parent, // Parent shell for nesting
bool isStateful = false, // Use StatefulShellRoute
String? initialRoute, // Auto-redirects from the shell's path to this path
String? pageBuilder, // Custom page builder function name
})
@AutoGoRouteBase
@AutoGoRouteBase({
String? initialLocation, // Initial route location
String? errorBuilder, // Error page builder function name
String? redirect, // Global redirect function name
String navigatorExtensionName = 'AutoGoRouteNavigation', // Extension name for navigation
})
Extensions #
GoRouterStateTypeExtension
T getParam(String key) // Get typed parameter
T getRequiredParam(String key) // Get required parameter
T getOptionalParam(String key, T defaultValue) // Get optional parameter
Map getTypedPathParameters() // Get all path parameters
Map getTypedQueryParameters() // Get all query parameters
bool hasParam(String key) // Check if parameter exists
TypeSafeNavigation
void goToRoute(RoutePaths route, {...}) // Navigate to route
void pushRoute(RoutePaths route, {...}) // Push route
void replaceRoute(RoutePaths route, {...}) // Replace current route
void goWithParams(T route, Map params) // Navigate with typed params
void goToRouteIfAuth(RoutePaths route, bool isAuth, {...}) // Conditional navigation
void safePop([Object? result]) // Safe pop operation
AutoGoRouteNavigation
A built-in extension on BuildContext
that provides a set of methods to navigate to routes. You can rename the extension with
@AutoGoRouteBase
annotation.
extension AutoGoRouteNavigation on BuildContext {
void goToProfileRoute({Map<String, String>? queries}) {
go(ProfileRouteRoute().pathWith(queries: queries));
}
void pushToProfileRoute({Map<String, String>? queries}) {
push(ProfileRouteRoute().pathWith(queries: queries));
}
void replaceWithProfileRoute({Map<String, String>? queries}) {
pushReplacement(ProfileRouteRoute().pathWith(queries: queries));
}
}
// Usage
context.goToProfileRoute();
context.pushToProfileRoute();
context.replaceWithProfileRoute();
Route Registry #
void register(RoutePaths route) // Register single route
void registerAll(List routes) // Register multiple routes
void validateAllRoutes() // Validate all routes
String generateDocumentation({...}) // Generate documentation
RegistryStatistics get statistics // Get registry statistics
Package Structure #
auto_go_route/
├── lib/
│ ├── auto_go_route.dart // Main export file
│ └── src/
│ ├── annotations/
│ │ └── auto_go_route.dart // Route annotations
│ ├── base/
│ │ ├── route_paths.dart // Base route class
│ │ ├── nested_route_paths.dart // Nested route base
│ │ └── shell_route_paths.dart // Shell route base
│ ├── extensions/
│ │ ├── go_router_state_extension.dart // Parameter extraction
│ │ ├── navigation_extensions.dart // Navigation helpers
│ │ └── string.dart // String utilities
│ ├── registry/
│ │ └── route_registry.dart // Route management
│ ├── utils/
│ │ └── route_utils.dart // Route utilities
│ └── exceptions/
│ └── route_exceptions.dart // Custom exceptions
└── generator/
├── lib/
│ ├── auto_go_route_generator.dart // Main generator export
│ ├── builder.dart // Build configuration
│ └── src/
│ ├── generators/
│ │ └── route_generator.dart // Code generator
│ └── utils/
│ └── generator_utils.dart // Generator utilities
├── build.yaml // Build configuration
└── pubspec.yaml // Generator dependencies
Migration Guide #
From manual GoRouter setup: #
Before:
GoRoute(
path: '/user/:id',
builder: (context, state) {
final id = state.pathParameters['id'] ?? '';
return UserPage(userId: id);
},
)
After:
@AutoGoRoute(path: '/user/:id')
class UserPage extends StatelessWidget {
final String id;
const UserPage({required this.id});
// ...
}
From other routing packages: #
- Replace route definitions with
@AutoGoRoute
annotations - Create a route base class extending
_$YourRouteClass
- Run code generation:
dart run build_runner build
- Update navigation calls to use generated route instances
- Register routes in
RouteRegistry
for additional features
Contributing #
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
Development Setup #
# Clone the repository
git clone https://github.com/itsarvinddev/auto_go_route.git
# Install dependencies
cd auto_go_route
flutter pub get
# Install generator dependencies
cd generator
dart pub get
cd ..
# Generate code
dart run build_runner build
# Run tests
flutter test
# Run example app
cd example
flutter run
License #
This project is licensed under the MIT License - see the LICENSE file for details.
Support #
- Github: itsarvinddev
- X: @itsarvinddev
- Issues: GitHub Issues
Made with ❤️ by Arvind Sangwan