routerino 0.8.1 copy "routerino: ^0.8.1" to clipboard
routerino: ^0.8.1 copied to clipboard

Add names to routes without a declarative pattern and without build_runner

Routerino #

pub package License: MIT

This opinionated package provides extension methods for BuildContext to push and pop routes.

Philosophy #

NO to a verbose declarative pattern like in go_router

Having all routes in one place is good but this information is already available if you write all routes in views/ or pages/.

Furthermore, you often find yourself jumping between several files to either find the parameters or to find the widget.

NO to build_runner

This is necessary for type-safety, but it slows down development and decreases the developer UX.

YES to type-safety

We call widget constructors directly. Don't pass arbitrary objects via route settings!

YES to sentry integration

Every route will have a name based on its class name. This is useful for sentry.

TLDR

I just want to push a widget and that's it!

Motivation #

The problems without using this package:

  1. Pushing a new route requires lots of boilerplate.
  2. Adding a name to the route requires you to write names twice (redundancy).
Navigator.push(
  context,
  MaterialPageRoute(
    builder: (_) => LoginPage(),
    settings: RouteSettings(name: 'LoginPage'), // so redundant!
  ),
);

Now you only need to write:

context.push(() => LoginPage());

Usage #

// push a route
context.push(() => MyPage());

// push a route (no animation)
context.pushImmediately(() => MyPage());

// push a route while removing all others
context.pushRoot(() => MyPage());

// push a route and remove the current one
context.pushReplacement(() => MyPage());

// push a route while removing all others (without animation)
context.pushRootImmediately(() => MyPage());

// push a route and removes all routes until the specified one
context.pushAndRemoveUntil(
  removeUntil: LoginPage,
  builder: () => MyPage(),
);

// push a bottom sheet
context.pushBottomSheet(() => MySheet());

// pop the most recent route
context.pop();

// pop until the specified page
context.popUntil(LoginPage);

// pop until the first page
context.popUntilRoot();

// remove a route from the stack
context.removeRoute(MyPage);

// push a route and wait for a result (type-safe)
final result = await context.pushWithResult<int, PickNumberPage>(() => PickNumberPage());

Initial Route #

It is recommended to add a RouterinoHome widget to your app.

This prevents having an unnamed initial route which causes trouble if you want to use popUntil.

MaterialApp(
  title: 'Flutter Example',
  home: RouterinoHome( // <-- add this
    builder: () => MyHomePage(),
  ),
);

context.popUntil(MyHomePage); // <-- works now

Global BuildContext #

Sometimes you want to push a route while you don't have access to BuildContext. There is a pragmatic way to solve this problem.

Setup:

MaterialApp(
  title: 'Flutter Example',
  navigatorKey: Routerino.navigatorKey, // <-- add this
  home: RouterinoHome(
    builder: () => MyHomePage(),
  ),
);

Access global context:

Routerino.context.push(() => MyPage());

Transitions #

You can configure the transition globally or per invocation.

// Set globally
Routerino.transition = RouterinoTransition.fade;

// uses "fade" transition
context.push(() => LoginPage());

// uses "noTransition" transition
context.push(() => RegisterPage(), transition: RouterinoTransition.noTransition);

Available transitions: material (default), cupertino, noTransition, fade, slide, slideJoined.

Type-safe Results #

You can push a route and wait for a result while achieving a high degree of type-safety.

You need to specify the exact generic type until https://github.com/dart-lang/language/issues/524 gets resolved.

Push a route:

final result = await context.pushWithResult<int, PickNumberPage>(() => PickNumberPage());

Specify the widget:

// add PopsWithResult<int> for type-safety
class PickNumberPage extends StatelessWidget with PopsWithResult<int> {
  const PickNumberPage({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            // use the type-safe popWithResult method
            popWithResult(context, 123);
          },
          child: Text('Pick Number'),
        ),
      ),
    );
  }
}

Sentry #

You want it to look like this?

sentry

MaterialApp(
  navigatorObservers: [
    SentryNavigatorObserver(), // add this 
  ],
  home: const InitPage(),
);

Obfuscation #

Routes do not have the correct class names if you enable Flutter obfuscation which makes sentry integration useless.

It is up to you. I don't value obfuscation that much.

Compiled flutter code is already hard to read.

21
likes
150
points
3.7k
downloads

Documentation

API reference

Publisher

verified publishertienisto.com

Weekly Downloads

Add names to routes without a declarative pattern and without build_runner

Repository

License

MIT (license)

Dependencies

flutter

More

Packages that depend on routerino