fluent_navigation

Package that provides a simple way to navigate within your app

Getting Started

Add dependencies

fluent_navigation: ^1.9.0

Create pages

// Page one (initial)
class PageOne extends StatelessWidget {
  const PageOne({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Page one")),
      body: Center(
        child: Column(
          children: [
            ElevatedButton(
              onPressed: () async {
                // Push to registered route two
                final result = await Fluent.get<NavigationApi>().pushTo("two");
                if (result != null) {
                  debugPrint("Result: $result");
                }
              },
              child: const Text("Push to second page"),
            ),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: () {
                // Navigate with params and query params
                Fluent.get<NavigationApi>().navigateTo(
                  "details",
                  params: {"id": "123"},
                  queryParams: {"tab": "info"},
                );
              },
              child: const Text("Navigate with parameters"),
            ),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: () {
                // Replace current route (useful for login flows)
                Fluent.get<NavigationApi>().replaceWith("home");
              },
              child: const Text("Replace with Home"),
            ),
          ],
        ),
      ),
    );
  }
}

// Page two
class PageTwo extends StatelessWidget {
  const PageTwo({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text("Page two")),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            // Check if can pop before popping
            if (Fluent.get<NavigationApi>().canPop()) {
              Fluent.get<NavigationApi>().pop(true);
            }
          },
          child: const Text("Go back to previous page"),
        ),
      ),
    );
  }
}

Create module and register routes

class ExampleModule extends FluentModule {

  @override
  Future<void> onCreate(Registry registry) async {
    registry
        // Initial route
        ..registerRoute(GoRoute(
          name: "one",
          path: "/one",
          builder: (context, state) => const PageOne(),
        ))
        // Route with parameters
        ..registerRoute(GoRoute(
          name: "details",
          path: "/details/:id",
          builder: (context, state) {
            final id = state.pathParameters["id"];
            final tab = state.uri.queryParameters["tab"];
            return DetailsPage(id: id, tab: tab);
          },
        ));
  }
}

Build module

void main() async {
  await Fluent.build([
    NavigationModule(initialLocation: "/one"),
    ExampleModule(),
  ]);

  runApp(const MainApp());
}

Use it

class App extends StatelessWidget {
    const App({super.key});

    @override
    Widget build(BuildContext context) {    
        final navigationApi = Fluent.get<NavigationApi>();
        
        return MaterialApp.router(
            title: "Fluent Navigation Demo",
            // The router configuration
            routerConfig: navigationApi.router,
            // Access the GlobalKey<NavigatorState> if needed
            // builder: (context, child) => MyWrapper(
            //    navigatorKey: navigationApi.navigatorKey,
            //    child: child!,
            // ),
        );
    }
}

Example

Libraries

fluent_navigation