browser_router 0.0.5 copy "browser_router: ^0.0.5" to clipboard
browser_router: ^0.0.5 copied to clipboard

An advanced navigation system for Flutter that enables typed routes, custom transitions, and robust overlay management.

Browser Router - Advanced Navigation for Flutter #

pub version

An advanced navigation system for Flutter that enables typed routes, custom transitions, and robust overlay management (Banners, Modals, Sheets).

Features #

  • Centralized Route Management: Define all your app routes in one place.
  • Typed Route Arguments: Pass strongly-typed arguments to your routes safely, with validation.
  • Custom Transitions: Easily implement custom page transitions (slide, fade, etc.) with a smart priority system.
  • Versatile Presentations: Display any route as a full page, a modal popup, or a swipeable bottom sheet using TraceRoute.
  • Semantic Navigation API: Create a reusable, semantic, and centralized navigation API for your app using Trace objects.
  • Deep Linking: Automatically parses URL query parameters and delivers them to new or existing screens.
  • Advanced Overlays & Popups: Show sequential banners, complex modals, and multi-level popups.

Installation #

Add this to your package's pubspec.yaml file:

dependencies:
  browser: ^0.0.1 # Replace with the latest version

Then, run flutter pub get in your terminal.


Getting Started #

  1. Define your routes

Create a list of BrowserRoute objects.

final routes = [
  BrowserRoute(
    path: '/',
    page: const HomeScreen(),
  ),
  BrowserRoute(
    path: '/profile',
    page: const ProfileScreen(),
  ),
];
  1. Wrap your app with Browser

Use the Browser widget at the root of your application.

import 'package:browser/browser.dart';
import 'package:flutter/widgets.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return Browser(
      routes: routes,
      defaultRoute: routes.first,
      builder: (context, routeObserver, generate) {
        return WidgetsApp(
          color: const Color(0xFFFFFFFF),
          navigatorObservers: [routeObserver],
          onGenerateRoute: generate,
          onGenerateInitialRoutes: (routePath) => [
            generate(
              RouteSettings(name: routePath, arguments: Map.from({})),
            ),
          ],
        );
      },
    );
  }
}
  1. Navigate

You can now navigate between screens using context.pushNamed.

// Navigate to the profile screen
context.pushNamed('/profile');

// Go back
context.pop();

Advanced Navigation #

browser provides powerful, unified methods for navigation.

Deep Linking #

If you navigate to a path that contains URL query parameters (e.g. /profile?id=123), browser automatically parses them into a DeepLinkParam object.

There are two ways to receive these parameters:

1. On a new screen

If the deep link pushes a new screen, that screen can get the parameters directly in its build method.

// In ProfileScreen's build method
final deepLinkParams = context.getArgument<DeepLinkParam>();
if (deepLinkParams != null) {
  final userId = deepLinkParams.params['id']; // "123"
}

2. On an existing screen (with Browser.watch)

If the deep link navigates to a screen that is already in the stack (like the HomeScreen), you can receive the parameters in the onAppear callback of Browser.watch.

// In HomeScreen's State
Widget build(BuildContext context) {
  return Browser.watch(
    onAppear: (context, deepLink) {
      // The `deepLink` parameter will be populated here
      if (deepLink != null) {
        final message = deepLink.params['message'];
        // ... update state with the message
      }
    },
    child: ...
  );
}

Presentation with TraceRoute #

A TraceRoute is an object that defines HOW a route is presented. The type of TraceRoute you provide determines the presentation style.

  • PageTraceRoute: The default. Presents the route as a standard, full-screen page.
  • PopupTraceRoute: Presents the route as a modal dialog.
  • SwipeTraceRoute: Presents the route as a swipeable bottom sheet.

Typed Arguments (args) #

This is the recommended way to pass data between screens.

1. Create an arguments class

class ProfileArgs extends RouteParams { ... }

2. Add validation to your route

BrowserRoute(
  path: '/profile',
  page: ProfileScreen(),
  validateArguments: (check, get) => check<ProfileArgs>(),
),

3. Push with arguments

context.pushNamed(
  '/profile',
  args: [ProfileArgs(userId: '123')],
);

4. Retrieve the arguments

final args = context.getArgument<ProfileArgs>();

Receiving Arguments from pop #

To receive a "result" from a screen that was popped, you must wrap the receiving widget with Browser.watch and check for your result arguments inside the onAppear callback.

// In the receiving screen (e.g., HomeScreen)
return Browser.watch(
  onAppear: (context, deepLink) {
    // Use getArgumentAndClean for one-time pop results
    final popArgs = context.getArgumentAndClean<PopResultArgs>();
    if (popArgs != null) {
      // ... update state with popArgs.result
    }
  },
  child: ...
);

getArgument vs. getArgumentAndClean #

  • getArgument<T>(): Reads an argument without removing it. Use for data needed to build a screen (e.g., a product ID).
  • getArgumentAndClean<T>(): Reads an argument and then removes it. Use for one-time events, like results from a pop, to avoid processing the same event multiple times.

Advanced Pattern: Semantic Navigation API with Trace #

For large applications, you can use the Trace class to create a centralized, reusable, and semantic API for all your navigation events.

1. Centralize Paths

enum AppPath {
  profile('/profile');
  const AppPath(this.path);
  final String path;
}

2. Create a Trace Wrapper

class AppTrace extends Trace {
  const AppTrace._({required super.path, super.args, super.traceRoute});

  factory AppTrace.toProfile({ required String userId }) {
    return AppTrace._(
      path: AppPath.profile.path,
      args: ProfileArgs(userId: userId),
    );
  }
}

3. Use the Semantic API

AppTrace.toProfile(userId: '123').push(context);

A Note on Flutter Web Routing Strategies #

This package works directly with Flutter's default web routing strategy, which uses a "hash" (or fragment) in the URL.

Default Strategy (Hash-based) #

By default, your Flutter web app's URLs will look like this:

https://yourapp.com/#/home
https://yourapp.com/#/profile/123?mode=edit

With this strategy, route arguments and parameters are managed on the client-side and work without any special configuration on your web server.

Path-based Strategy #

If you prefer cleaner, more SEO-friendly URLs without the #:

https://yourapp.com/home
https://yourapp.com/profile/123?mode=edit

You can enable the "path-based" routing strategy. To do so, follow these two steps:

  1. Enable the Strategy in Flutter: Call usePathUrlStrategy() at the beginning of your main() function in main.dart.

    // main.dart
    import 'package:flutter/material.dart';
    import 'package:flutter_web_plugins/url_strategy.dart';
    
    void main() {
      // Call this function before runApp()
      usePathUrlStrategy();
      runApp(const MyApp());
    }
    
  2. Configure Your Web Server: This is a critical step. You must configure your production server (Nginx, Apache, Firebase Hosting, etc.) to redirect all requests to your index.html file. Without this, users who directly access an internal URL of your app will get a 404 error.

    For more details on how to configure your server, see the official Flutter documentation.

By following these steps, browser will work perfectly with the routing strategy you choose.


License #

This project is licensed under the MIT License - see the LICENSE file for details.


Maintainers & Contributors ✨ #

Big thanks go to these wonderful people who have contributed to the project:

Eduardo Martínez Catalá
Eduardo Martínez Catalá
Cayetano Bañón Rubio
Cayetano Bañón Rubio
Jesus Bernabeu
Jesus Bernabeu
0
likes
160
points
464
downloads

Publisher

verified publisheryaminokishi.com

Weekly Downloads

An advanced navigation system for Flutter that enables typed routes, custom transitions, and robust overlay management.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

collection, equatable, flutter, nested, pool

More

Packages that depend on browser_router