agentsclimarketplace

Flutter autoroute

Skill Poorgramer-Zack/dart-expert-skills/skills/flutter-autoroute

A comprehensive library of modular Agent Skills for Flutter & Dart development

Install
npx -y skills add Poorgramer-Zack/dart-expert-skills --skill flutter-autoroute

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

2 things to look at

  • no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
  • 6 stars6 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Implements type-safe Flutter routing using AutoRoute v11 with code generation and @RoutePage annotations. Activates when setting up AutoRoute navigation, configuring AutoRouterConfig or RootStackRouter, generating route files with build_runner, using @RoutePage, @PathParam, or @QueryParam annotations, implementing AutoTabsRouter for bottom navigation tabs, adding navigation guards with AutoRouteGuard, setting up nested or child routes, handling type-safe route parameters, or migrating from string-based Navigator routing to compile-time-verified routes. Ideal for large apps requiring refactoring confidence and zero string-based routing errors.

SKILL.md

6.3 KB, as published. Nobody here has run it

AutoRoute Type-Safe Navigation Guide (v11.x)

Goal

Implement type-safe routing using AutoRoute with compile-time code generation. AutoRoute v11+ uses @RoutePage annotations to eliminate boilerplate and ensure type safety through generated route configurations.

Process

Phase 1: Install Dependencies

dependencies:
  auto_route: ^11.1.0

dev_dependencies:
  auto_route_generator: ^11.1.0
  build_runner: ^2.14.1

Phase 2: Annotate Pages

import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';

@RoutePage()
class HomeScreen extends StatelessWidget {
  const HomeScreen({super.key});
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Home')),
      body: Center(
        child: ElevatedButton(
          onPressed: () => context.router.push(ProfileRoute()),
          child: Text('Go to Profile'),
        ),
      ),
    );
  }
}

@RoutePage()
class ProfileScreen extends StatelessWidget {
  const ProfileScreen({super.key});
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Profile')),
    );
  }
}

// Type-safe parameters
@RoutePage()
class UserScreen extends StatelessWidget {
  final String userId;
  final String? referrer;  // Optional parameter
  
  const UserScreen({
    @PathParam('id') required this.userId,
    @QueryParam('ref') this.referrer,
    super.key,
  });
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('User $userId')),
      body: Text('Referrer: ${referrer ?? "none"}'),
    );
  }
}

Phase 3: Define Router Configuration

import 'package:auto_route/auto_route.dart';

part 'app_router.gr.dart';

@AutoRouterConfig()
class AppRouter extends RootStackRouter {
  @override
  List<AutoRoute> get routes => [
    AutoRoute(page: HomeRoute.page, initial: true),
    AutoRoute(page: ProfileRoute.page),
    AutoRoute(page: UserRoute.page, path: '/user/:id'),
    AutoRoute(page: LoginRoute.page, path: '/login'),
  ];
}

Phase 4: Generate Routes

flutter pub run build_runner build --delete-conflicting-outputs

# Or watch mode for development
flutter pub run build_runner watch

Phase 5: Initialize Router

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  final _appRouter = AppRouter();
  
  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      routerConfig: _appRouter.config(),
    );
  }
}

Phase 6: Navigation

// Push route (type-safe!)
context.router.push(UserRoute(userId: '123'));

// Push with query params
context.router.push(UserRoute(userId: '123', referrer: 'home'));

// Replace
context.router.replace(ProfileRoute());

// Pop
context.router.pop();

// Pop until
context.router.popUntil((route) => route.settings.name == HomeRoute.name);

// Navigate to nested route
context.router.navigate(ProfileRoute(children: [
  EditProfileRoute(),
]));

Phase 7: Nested Navigation & Tabs

@AutoRouterConfig()
class AppRouter extends RootStackRouter {
  @override
  List<AutoRoute> get routes => [
    AutoRoute(
      page: DashboardRoute.page,
      initial: true,
      children: [
        AutoRoute(page: HomeRoute.page, initial: true),
        AutoRoute(page: SearchRoute.page),
        AutoRoute(page: ProfileRoute.page),
      ],
    ),
  ];
}

@RoutePage()
class DashboardScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return AutoTabsRouter(
      routes: const [
        HomeRoute(),
        SearchRoute(),
        ProfileRoute(),
      ],
      builder: (context, child) {
        final tabsRouter = AutoTabsRouter.of(context);
        return Scaffold(
          body: child,
          bottomNavigationBar: BottomNavigationBar(
            currentIndex: tabsRouter.activeIndex,
            onTap: tabsRouter.setActiveIndex,
            items: const [
              BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Home'),
              BottomNavigationBarItem(icon: Icon(Icons.search), label: 'Search'),
              BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Profile'),
            ],
          ),
        );
      },
    );
  }
}

Phase 8: Guards (Authentication)

class AuthGuard extends AutoRouteGuard {
  @override
  void onNavigation(NavigationResolver resolver, StackRouter router) {
    if (AuthService.instance.isLoggedIn) {
      resolver.next(); // Proceed
    } else {
      resolver.redirect(LoginRoute(
        onResult: (success) {
          if (success) {
            resolver.next();
          }
        },
      ));
    }
  }
}

// Apply guard
@AutoRouterConfig()
class AppRouter extends RootStackRouter {
  @override
  List<AutoRoute> get routes => [
    AutoRoute(page: LoginRoute.page),
    AutoRoute(
      page: ProfileRoute.page,
      guards: [AuthGuard()],  // Protected route
    ),
  ];
}

Constraints

  • Breaking Changes in v11: Old syntax from v10 is incompatible. Use @RoutePage() only.
  • Type Safety: All route parameters are type-checked at compile time.
  • Code Generation: Must run build_runner after route changes.
  • Unique Route Names: Page names must be unique across the app.
  • Guard Order: Guards execute in the order they're listed.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.