vrouter 1.2.1 icon indicating copy to clipboard operation
vrouter: ^1.2.1 copied to clipboard

A navigation package that makes navigation and routing easy on every platform. Built on top of Navigator 2.

VRouter logo

VRouter website Join our discord Github repo pub package

A Flutter package that makes navigation and routing easy.

Learn more at vrouter.dev

Here are a few things that this package will make easy:

  • Automated web url handling
  • Nesting routes
  • Transition
  • Advanced url naming
  • Reacting to route changing
  • Customizable pop events
  • And much more...

Index #

Getting started #

VRouter #

VRouter is a widget which handles the navigation, it acts as a MaterialApp but also takes a routes arguments.

 debugShowCheckedModeBanner: false, // VRouter acts as a MaterialApp
 routes: [...], // Put your VRouteElements here

VRouteElements #

VRouteElements are the building blocs of your routes.

Note that they are not widgets but the way you use them is very similar to widgets.

VWidget #

VWidget maps a path to a widget:

VWidget(path: '/login', widget: LoginScreen())

VGuard #

VGuard allows you to take actions when the route is accessed/leaved:

 beforeEnter: (vRedirector) async => , // Triggered when a route in stackedRoutes is first displayed
 beforeUpdate: (vRedirector) async => , // Triggered when a route in stackedRoutes is displayed but changes
 beforeLeave: (vRedirector, _) async => , // Triggered when VGuard is not part of a new route
 stackedRoutes: [...],

VRouteRedirector #

VRouteRedirector redirects from a route to another:

VRouteRedirector(path: '/old/home', redirectTo: '/home')

VNester #

VNester are used when you need to nested widgets instead of stacking them:

 path: '/home',
 widgetBuilder: (child) => MyScaffold(body: child), // child will take the value of the widget in nestedRoutes
 nestedRoutes: [
   VWidget(path: 'profile', widget: ProfileScreen()), // path '/home/profile'
   VWidget(path: 'settings', widget: SettingsScreen()), // path '/home/settings'

VPopHandler #

VPopHandler helps you control pop events:

 onPop: (vRedirector) async =>, // Called when this VRouteElement is popped
 onSystemPop: (vRedirector) async =>, // Called when this VRouteElement is popped by android back button
 stackedRoutes: [...],

Navigating is easy, just access VRouter with context.vRouter and navigate:

context.vRouter.to('/home'); // Push the url '/home'

context.vRouter.toSegments(['home', 'settings']); // Push the url '/home/settings'

Useful notions #

Composition #

VRouteElements are designed like widgets: compose them to create the route you need.

Compose VRouteElements #

To compose VRouteElements, use the stackedRoutes attribute (or the nestedRoutes attribute for VNester):

// Composing a VGuard and a VWidget
 beforeEnter: (vRedirector) async => !isLoggedIn ? vRedirector.to('/login') : null,
 stackedRoutes: [
   VWidget(path: '/home', widget: HomeScreen()),

Create custom VRouteElements #

You can even create your own VRouteElement, as you extend VWidget. You just need to extends VRouteElementBuilder:

class HomeRoute extends VRouteElementBuilder {
 static String home = '/home';

 List<VRouteElement> buildRoutes() {
   return [
       // LoginRoute.login = '/login' for example
       beforeEnter: (vRedirector) async => !isLoggedIn ? vRedirector.to(LoginRoute.login) : null,
       stackedRoutes: [
         VWidget(path: home, widget: HomeScreen()),

and then use this VRouteElement as any other:

 routes: [

This can be used to:

  • Separate you different routes in different VRouteElement
  • Create reusable VRouteElement
  • Use static String to organise your paths

Note: you often want to use a shared VNester in different VRouteElementBuilders, for this specific use case, see vrouter.dev/Custom VRouteElement And Scaling

Path #

Relative path #

Paths can be relative: if you don’t start your path with /. If you use null, the path will be the one of the parent:

 path: '/home',
 widgetBuilder: (child) => MyScaffold(body: child),
 nestedRoutes: [
   VWidget(path: null, widget: HomeScreen()), // Matches '/home'
   VWidget(path: 'settings', widget: SettingsScreen()), // Matches '/home/settings'

Path parameters #

Paths can have path parameters, just use “:” in front of the path parameter’s name:

VWidget(path: '/user/:id', widget: UserScreen())

And access it in your widgets using:


Wildcards #

Wildcards are noted * and there are of one of two types:

  • Trailing wildcards (a path ending with *) will match everything
  • an in-path wildcard (a wildcard between slashes) will match one word
// Redirects any path to '/unknown'
VRouteRedirector(path: '*', redirectTo: '/unknown')

Path parameters regexp #

Path parameters can use regex, just put the regex in parentheses. This is often used in VRedirector to redirect any unknown route:

// The path parameter name is “bookId” and it uses the regex “\d+” to match only digits
VWidget(path: r':bookId(\d+)', widget: BookScreen())

Note that such a VRedirector should be used as your last route otherwise it will always be matched.

Aliases #

Use aliases for multiple paths:

// Matches '/settings' and '/other'
VWidget(path: '/settings', aliases: ['/other'], widget: SettingsScreen())

VRedirector #

You often want to redirect or stop the current redirection in VGuard and VPopHandler. For that purpose, you get a VRedirector:

 beforeEnter: (vRedirector) async => !isLoggedIn ? vRedirector.to('/login') : null,
 stackedRoutes: [...],

VRouterData #

VRouter contains data (such as the path or path parameters) that you might want to access in your widget tree. There are 2 ways of doing do:

// Use the context

// Use the builder constructor of some VWidget or VNester
  path: '/:id', 
  builder: (context, state) => Book(id: state.pathParameters['id'] as int),

Go Beyond #

We have just scratched the surface of what VRouter can do. Here are a few other things which you might like.

Initial url #

Maybe you want to redirect people to a certain part of your app when they first launch it, then use initialUrl:

 initialUrl: '/home',
 routes: [...],

Logs #

By default, VRouter shows logs of every navigation events.

You can remove these logs using VLogs.none:

  logs: VLogs.none,
  routes: [...],

Named route #

You might have to access a deeply nested VRouteElement and don’t want to have to write the full url. Just give a name to this VRouteElement:

VWidget(path: 'something', widget: SomeWidget(), name: 'deep')

And navigate using toNamed:


Transitions #

You can either specify a default transition in VRouter, or a custom one in VWidget or VNester

 // Default transition
 buildTransition: (animation1, _, child) => FadeTransition(opacity: animation1, child: child),
 routes: [
   // The custom ScaleTransition will play for '/user'
     path: '/user',
     widget: UsersScreen(),
     buildTransition: (animation1, _, child) => ScaleTransition(scale: animation1, child: child),
   // The default FadeTransition will play for '/settings'
   VWidget(path: '/settings', widget: SettingsScreen()),

Much more #

There is so much more that this package can do, check out the example or have a look at the vrouter.dev website for more documentation and more examples.

Also don’t hesitate to join us on discord !

pub points


verified publisher iconvrouter.dev

A navigation package that makes navigation and routing easy on every platform. Built on top of Navigator 2.

Repository (GitHub)
View/report issues


API reference


Icon for licenses.MIT (LICENSE)


flutter, move_to_background, url_launcher, url_strategy


Packages that depend on vrouter