Qlevar Router (QR)

likes popularity pub points codecov

Qlevar router is flutter package to help you with managing your project routing, navigation, deep linking, route params, etc ... With Navigator 2.0 Manage your project routes and create nested routes. Change only one widget on your page when navigating to the new route. Navigate without context from anywhere to anywhere.

// Define your routes
class AppRoutes {
  static String homePage = 'Home Page';
  static String userPage = 'User Page';
  final routes = [
    QRoute(name: homePage, path: '/', builder: () => HomePage()),   
        name: userPage,
        path: '/user/:userId',
        builder: () => HomePage(),
        children: [
          QRoute(name: homePage, path: '/settings', builder: () => SettingsPage()),
          QRoute(name: homePage, path: '/profile', builder: () => ProfilePage()),
    QRoute(path: '/products/:category(\w)', builder: () => ProductCategory()),
    QRoute(path: '/products/:id((^[0-9]\$))', builder: () => ProductDetails()),

// Create your app
class MyApp extends StatelessWidget {
  Widget build(BuildContext context) => MaterialApp.router(
      routeInformationParser: QRouteInformationParser(),
      routerDelegate: QRouterDelegate(AppRoutes().routes));

// from anywhere in your code navigate to new page with
QR.toName(AppRoutes.userPage, param:{'userId':2});
// or

QR.to('/user/6/profile')  // Here the Stack will be HomePage -> ProfilePage()
QR.to('products/456')     // Will call ProductDetails page
QR.to('products/garden')  // Will call ProductCategory page
QR.back()                 // Go back to the last page(in this case 'products/456')
QR.currentPath            // will show the current path 

you want to work with the basic functions from the navigator just set which navigator to use with QR.activeNavigatorName and then call it and use it

  QR.navigator.currentRoute //Get the current route for this navigator

  QR.navigator.pushName(String name, {Map<String, dynamic>? params})
  QR.navigator.push(String path);

  QR.navigator.replaceAll(String path);
  QR.navigator.replaceAllWithName(String name, {Map<String, dynamic>? params});

  QR.navigator.replace(String path, String withPath);

or just call the navigator QR.navigatorOf('Dashboard')

Use this functions to see your navigators and Stack history and active pages in your project for better understanding on where you are in your project and how to order you pages.

QR.getActiveTree() // Will show you a dialog contains the tree of the active navigator and pages
QR.history.debug() // will show you a dialog contains the history stack for your current page.


The example Projects

Show Demo

You can find the demo code in the example project

The Samples Project

You can checkout the samples project for more samples and to test some use case


send your params with the route, or set them before routing and call them from the next page. The params could be any object type.

Route Component

QRoute(path: '/:orderId',page: (child) => OrderDetails()),

// and this receive it in your page
final orderId = QR.params['orderId'].toString()

Query Param


// and this receive it in your page
final itemName = QR.params['itemName'].toString()
final numbers = QR.params['numbers']

Params features

  • keepAlive: by default the param will be deleted when navigating to new route that does not contains it, so if you don't what to deleted it in this case set this property to true and the package will not deleted as long as this property is true
  • onChange: set function to be called when this param will be changed it give the current value and the new value
  • onDelete: set function to be called when this param will be deleted
  • asInt: Will return the value as int?
  • asDouble: Will return the value as double
  • valueAs: Will return the value as the given type


with middleware you can set a custom actions to run with different event when you navigate to define them add QMiddlewareBuilder or a custom class that extends 'QMiddleware' them in you route, they will be called in the same order they are defined in.

    path: '/home',
    builder: () {
      return HomePage();
    middleware: [
          onEnterFunc: () => print('-- Enter Parent page --'),
          onExitFunc: () => print('-- Exit Parent page --'),
          onMatchFunc: () => print('-- Parent page Matched --')),

class AuthMiddleware extends QMiddleware{
  final dataStorage = // Get you Data storage
  bool canPop() => dataStorage.canLeave;
  Future<String?> redirectGuard(String path) async => dataStorage.isLoggedIn ? null: '/parent/child-2';


you can redirect to new page whenever a page is called using the redirectGuard.

The redirectGuard give the path als parameter and takes the new path to redirect to. or it takes null so the page can be accessed.


can this route pop, called when trying to remove the page.


This method will be called every time a path match it.


This method will be called before adding the page to the stack and before the page building


This method will be called before removing the page from the stack

Not found page

you can set your custom not found page to show it whenever page was not found, or a default one will be set.

  QR.settings.notFoundPage = QRoute(path: '/404', builder: ()=> NotFoundPage())

Page Transition

To chose the Transition for you page set the QRoute.pageType to the of the types:

  • QPlatformPage: This type will be set as QCupertinoPage on IOS devises otherwise it will be QMaterialPage.
  • QMaterialPage: It will use the default MaterialRouteTransition
  • QCupertinoPage: It will use the default CupertinoRouteTransition
  • QCustomPage: to define a custom transition for your page.
  • QSlidePage: a predefined slide transition

Remove Url Hashtag

If you what to remove the hashtag from the url place in you main method

void main() {

Note: sometimes in release mode you could get error when you remove the hashtag, to fix it please see this