Auto Route

pub package License: MIT

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 FarmerRegistrationPage to /farmer-registration
  • 🏷️ Auto-generated names - Converts FarmerRegistrationPage to FarmerRegistration
  • 🔗 Path parameters - Support for :id and other path params
  • 📦 Bloc integration - Automatic BlocProvider wrapping
  • 🎯 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_annotation and json_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

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.