GoProvider

GoProvider aims to simplify provider scoping within go_router routes, offering:

  • 🎯 Scoped Simplicity: Route-specific state access for cleaner code.
  • 🏗️ Modular Design: No more 1.000 providers on the top of your app.
  • ✨ Auto-Lifecycle: Providers inits on go and auto-disposes on route pop.
  • 🚀 Streamlined State Management: Effortless integration with provider and flutter_bloc.
  • 🚌 Bus-proof: An easy-to-maintain, single-file library you can copy-paste, just in case.

The Problem

routes: [
  GoRoute(
    path: '/',
    builder: (context, state) => LoginPage(), // ❌ can't access UserState
  ),
  GoRoute(
    path: '/home',
    builder: (context, state) => ChangeNotifierProvider( // or BlocProvider
      create: (_) => UserState(),
      child: const HomePage(), // ✅ can access UserState
    ),
    routes: [
      GoRoute(
        path: 'details',
        builder: (context, state) => const DetailsPage(), // ❌ throws ProviderNotFoundException
      ),
    ],
  ),
]

GoProvider Solution

routes: [
  GoRoute(
    path: '/',
    builder: (context, state) => LoginPage(), // ❌ can't access UserState
  ),
  GoProviderRoute(
    path: '/home',
    providers: [
      ChangeNotifierProvider(create: (_) => UserState()), // or BlocProvider
    ],
    builder: (context, state) => const HomePage(), // ✅ can access UserState
    routes: [
      GoRoute(
        path: 'details',
        builder: (context, state) => const DetailsPage(), // ✅ can access UserState too!
      ),
    ],
  ),
]

You can also use ShellProviderRoute

routes: [
  ShellProviderRoute(
    providers: [
      ChangeNotifierProvider(create: (_) => FooState()), // or BlocProvider
    ],
    builder: (context, state, child) => ShellPage(child: child), // ✅ can access FooState
    routes: [
      GoRoute(
        path: '/a',
        builder: (context, state) => const PageA(), // ✅ can access FooState
      ),
      GoRoute(
        path: '/b',
        builder: (context, state) => const PageB(), // ✅ can access FooState
      ),
    ],
  ),
]

Issues

Since GoProviderRoute has its own Navigator, the canPop method will always return false. This means that the implicit back/close button wont show up. This a known issue when using ShellRoute routes: github.com/flutter/flutter/issues/144687

For leveraging GoRouter's implicit pop issue, you can use GoPopButton:

GoPopButton(), // CloseButton/BackButton that pops the current route (like AppBar's leading)

Also prefer using context.pop instead of Navigator.pop inside GoProviderRoute routes.

Contribution

Contributions are welcome! Feel free to submit pull requests or open issues on our GitHub repository. Don't forget to star/like the project if you like it.

Libraries

go_provider