Popular Searches
Popular Course Categories
Popular Courses

Named Routes in Flutter

Flutter Navigation & Screens


Named Routes in Flutter


Named Routes in Flutter provide a way to navigate between screens using unique string names instead of directly creating a route with a screen widget every time. For example, instead of repeatedly writing a complete MaterialPageRoute, you can define a route such as /details and navigate to it using Navigator.pushNamed().


Named routes are configured through the routes property of MaterialApp or CupertinoApp. Flutter's current documentation notes that named routes are not recommended for most new applications, especially when advanced deep-linking or routing requirements exist. For such applications, Navigator with explicit routes or a routing package such as go_router may be more suitable.




1. What Are Named Routes?


A named route is a route identified by a unique string. Each route name is mapped to a screen widget in the application's routing configuration.


For example:


'/': HomeScreen
'/login': LoginScreen
'/profile': ProfileScreen
'/settings': SettingsScreen
'/details': DetailsScreen

Instead of directly creating a route every time, you can navigate by using the route name:


Navigator.pushNamed(context, '/details');

Flutter looks up the route name and builds the screen associated with that name.




2. Why Use Named Routes?


Named routes can make navigation code easier to read when several parts of an application need to navigate to the same screen.


Without Named Routes


Navigator.push(
  context,
  MaterialPageRoute(
    builder: (context) => const ProfileScreen(),
  ),
);

With Named Routes


Navigator.pushNamed(context, '/profile');

With named routes, the route configuration is maintained in one place, while individual screens only need to use the route name.




3. Important Properties for Named Routes












Property or MethodPurpose
routesDefines a map of route names and screen builders.
initialRouteSpecifies the first named route displayed when the application starts.
homeDefines the initial screen directly.
Navigator.pushNamed()Opens a screen using its route name.
Navigator.pop()Closes the current route and returns to the previous screen.
Navigator.pushNamedAndRemoveUntil()Opens a named route and removes previous routes according to a condition.
onGenerateRouteCreates routes dynamically when navigation requires custom logic.
onUnknownRouteHandles route names that cannot be resolved.



4. Defining Named Routes in MaterialApp


Named routes are defined using the routes property of MaterialApp. The property accepts a map where each key is a route name and each value is a widget builder.


Basic Syntax


MaterialApp(
  initialRoute: '/',
  routes: {
    '/': (context) => const HomeScreen(),
    '/details': (context) => const DetailsScreen(),
  },
);

In this example:



  • '/' represents the Home Screen.

  • '/details' represents the Details Screen.

  • initialRoute: '/' tells Flutter to start with the Home Screen.

  • Each route value is a function that returns a widget.




5. Route Naming Conventions


Flutter route names commonly use a path-like format beginning with a forward slash.











Route NameExample Screen
/Home Screen
/loginLogin Screen
/registerRegistration Screen
/profileProfile Screen
/productsProduct List Screen
/product-detailsProduct Details Screen
/settingsSettings Screen

Use meaningful and consistent route names so that the purpose of each route is easy to understand.




6. Creating a Basic Named Routes Application


The following application defines two named routes: Home Screen and Second Screen.


import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Named Routes Demo',
      initialRoute: '/',
      routes: {
        '/': (context) => const HomeScreen(),
        '/second': (context) => const SecondScreen(),
      },
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Home Screen'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pushNamed(context, '/second');
          },
          child: const Text('Open Second Screen'),
        ),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Second Screen'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: const Text('Go Back'),
        ),
      ),
    );
  }
}


How the Example Works



  1. The application starts with the route /.

  2. The route / displays HomeScreen.

  3. The user taps the Open Second Screen button.

  4. Navigator.pushNamed(context, '/second') opens the second screen.

  5. The route /second displays SecondScreen.

  6. The user taps Go Back.

  7. Navigator.pop(context) removes the current route.

  8. The user returns to HomeScreen.




7. Understanding the routes Property


The routes property contains a map of route names and widget builders.


routes: {
  '/': (context) => const HomeScreen(),
  '/profile': (context) => const ProfileScreen(),
  '/settings': (context) => const SettingsScreen(),
}

The map can be understood as follows:







KeyValue
'/'Builds HomeScreen
'/profile'Builds ProfileScreen
'/settings'Builds SettingsScreen

When a named route is requested, Flutter searches the route map for the matching name.




8. Using initialRoute


The initialRoute property determines which named route is displayed when the application starts.


MaterialApp(
  initialRoute: '/login',
  routes: {
    '/login': (context) => const LoginScreen(),
    '/home': (context) => const HomeScreen(),
  },
);

In this example, the application starts with LoginScreen because initialRoute is set to /login.


Important Note


When using initialRoute, do not also define a home property for the same application configuration. Use either a direct home screen or an initial named route.




9. Difference Between home and initialRoute








homeinitialRoute
Accepts a widget directly.Accepts a route name.
Useful for simple applications.Useful when starting with a named route.
Example: home: const HomeScreen()Example: initialRoute: '/login'
Automatically represents the default / route.Must refer to a route configured in the routing system.



10. Navigating with Navigator.pushNamed()


The Navigator.pushNamed() method opens a route using its string name.


Syntax


Navigator.pushNamed(
  context,
  '/profile',
);

Example


ElevatedButton(
  onPressed: () {
    Navigator.pushNamed(context, '/profile');
  },
  child: const Text('Open Profile'),
)

Flutter finds the route named /profile in the configured route map and displays the associated screen.




11. Closing a Named Route with Navigator.pop()


Named routes are still managed by the Navigator stack. Therefore, the current named route can be closed using Navigator.pop().


ElevatedButton(
  onPressed: () {
    Navigator.pop(context);
  },
  child: const Text('Go Back'),
)

The route name does not need to be provided when going back. The Navigator removes the current route and reveals the previous route.




12. Named Routes Navigation Flow


Home Screen
    |
    | Navigator.pushNamed(context, '/profile')
    ↓
Profile Screen
    |
    | Navigator.pushNamed(context, '/settings')
    ↓
Settings Screen
    |
    | Navigator.pop(context)
    ↓
Profile Screen
    |
    | Navigator.pop(context)
    ↓
Home Screen



13. Centralizing Route Names


Writing route names directly in many files can lead to spelling mistakes. A common practice is to store route names as constants in a separate class.


Route Constants


class AppRoutes {
  static const String home = '/';
  static const String login = '/login';
  static const String profile = '/profile';
  static const String settings = '/settings';
}

Using Route Constants


MaterialApp(
  initialRoute: AppRoutes.home,
  routes: {
    AppRoutes.home: (context) => const HomeScreen(),
    AppRoutes.login: (context) => const LoginScreen(),
    AppRoutes.profile: (context) => const ProfileScreen(),
    AppRoutes.settings: (context) => const SettingsScreen(),
  },
);

Navigating with Route Constants


Navigator.pushNamed(
  context,
  AppRoutes.profile,
);

This approach helps maintain consistent route names throughout the application.




14. Complete Example Using Centralized Route Names


import 'package:flutter/material.dart';

class AppRoutes {
  static const String home = '/';
  static const String profile = '/profile';
  static const String settings = '/settings';
}

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Route Constants Demo',
      initialRoute: AppRoutes.home,
      routes: {
        AppRoutes.home: (context) => const HomeScreen(),
        AppRoutes.profile: (context) => const ProfileScreen(),
        AppRoutes.settings: (context) => const SettingsScreen(),
      },
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Home'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(
              onPressed: () {
                Navigator.pushNamed(
                  context,
                  AppRoutes.profile,
                );
              },
              child: const Text('Open Profile'),
            ),
            const SizedBox(height: 12),
            ElevatedButton(
              onPressed: () {
                Navigator.pushNamed(
                  context,
                  AppRoutes.settings,
                );
              },
              child: const Text('Open Settings'),
            ),
          ],
        ),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Profile'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: const Text('Back to Home'),
        ),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Settings'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: const Text('Back to Home'),
        ),
      ),
    );
  }
}




15. Passing Arguments to Named Routes


Sometimes a screen needs additional data. For example, a Product Details screen may need a product ID, product name, or price.


Flutter allows arguments to be passed through the arguments parameter of Navigator.pushNamed().


Basic Syntax


Navigator.pushNamed(
  context,
  '/details',
  arguments: 'Flutter Course',
);

Multiple values can be passed using a map:


Navigator.pushNamed(
  context,
  '/details',
  arguments: {
    'id': 101,
    'name': 'Flutter Course',
    'price': 4999,
  },
);



16. Receiving Arguments with ModalRoute


The destination screen can read the arguments using ModalRoute.of(context).


Complete Example


import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      initialRoute: '/',
      routes: {
        '/': (context) => const HomeScreen(),
        '/details': (context) => const DetailsScreen(),
      },
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Home Screen'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pushNamed(
              context,
              '/details',
              arguments: {
                'id': 101,
                'name': 'Flutter Course',
              },
            );
          },
          child: const Text('Open Details'),
        ),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    final arguments = ModalRoute.of(context)!.settings.arguments
        as Map<String, dynamic>;

    final int productId = arguments['id'] as int;
    final String productName = arguments['name'] as String;

    return Scaffold(
      appBar: AppBar(
        title: const Text('Details Screen'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Product ID: $productId'),
            Text('Product Name: $productName'),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: () {
                Navigator.pop(context);
              },
              child: const Text('Go Back'),
            ),
          ],
        ),
      ),
    );
  }
}


Important Points



  • arguments can contain a string, number, map, list, or custom object.

  • The receiving screen must know the expected data type.

  • Type casting should be performed carefully.

  • For complex data, a custom argument class can improve readability and type safety.




17. Passing a Custom Object as Arguments


Instead of passing a map, you can create a custom Dart class to represent route arguments.


Creating an Argument Class


class ProductArguments {
  final int id;
  final String name;

  const ProductArguments({
    required this.id,
    required this.name,
  });
}


Passing the Object


Navigator.pushNamed(
  context,
  '/details',
  arguments: const ProductArguments(
    id: 101,
    name: 'Flutter Course',
  ),
);

Receiving the Object


final arguments = ModalRoute.of(context)!.settings.arguments
    as ProductArguments;

final int productId = arguments.id;
final String productName = arguments.name;


Custom argument classes are useful when a route requires multiple related values.




18. Using onGenerateRoute


The onGenerateRoute property allows you to create routes dynamically. It receives a RouteSettings object containing the requested route name and optional arguments.


Basic Syntax


MaterialApp(
  onGenerateRoute: (settings) {
    if (settings.name == '/details') {
      return MaterialPageRoute(
        builder: (context) => const DetailsScreen(),
        settings: settings,
      );
    }

    return MaterialPageRoute(
      builder: (context) => const NotFoundScreen(),
    );
  },
);


This approach is useful when route creation requires conditions, validation, custom arguments, or dynamic logic.




19. Complete onGenerateRoute Example


import 'package:flutter/material.dart';

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

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      title: 'Generated Routes Demo',
      initialRoute: '/',
      onGenerateRoute: (settings) {
        switch (settings.name) {
          case '/':
            return MaterialPageRoute(
              builder: (context) => const HomeScreen(),
              settings: settings,
            );
          case '/profile':
            return MaterialPageRoute(
              builder: (context) => const ProfileScreen(),
              settings: settings,
            );
          case '/settings':
            return MaterialPageRoute(
              builder: (context) => const SettingsScreen(),
              settings: settings,
            );
          default:
            return MaterialPageRoute(
              builder: (context) => const NotFoundScreen(),
              settings: settings,
            );
        }
      },
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Home'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pushNamed(context, '/profile');
          },
          child: const Text('Open Profile'),
        ),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Profile'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: const Text('Go Back'),
        ),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Settings'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: () {
            Navigator.pop(context);
          },
          child: const Text('Go Back'),
        ),
      ),
    );
  }
}

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Page Not Found'),
      ),
      body: const Center(
        child: Text('The requested route does not exist.'),
      ),
    );
  }
}




20. Handling Unknown Routes


If a user attempts to navigate to a route that is not defined, the application should provide a suitable fallback screen.


A fallback can be configured using onUnknownRoute.


MaterialApp(
  routes: {
    '/': (context) => const HomeScreen(),
    '/profile': (context) => const ProfileScreen(),
  },
  onUnknownRoute: (settings) {
    return MaterialPageRoute(
      builder: (context) => const NotFoundScreen(),
    );
  },
);

This allows the application to display a custom error screen instead of failing silently when a route cannot be found.




21. Named Route Navigation with a Drawer


A Navigation Drawer often contains links to different sections of an application. Named routes can be used to navigate from each drawer item.


Drawer(
  child: ListView(
    children: [
      const DrawerHeader(
        child: Text('Application Menu'),
      ),
      ListTile(
        leading: const Icon(Icons.home),
        title: const Text('Home'),
        onTap: () {
          Navigator.pushNamed(context, '/');
        },
      ),
      ListTile(
        leading: const Icon(Icons.person),
        title: const Text('Profile'),
        onTap: () {
          Navigator.pushNamed(context, '/profile');
        },
      ),
      ListTile(
        leading: const Icon(Icons.settings),
        title: const Text('Settings'),
        onTap: () {
          Navigator.pushNamed(context, '/settings');
        },
      ),
    ],
  ),
)

When navigating from a drawer, you may also want to close the drawer before or after navigation, depending on the layout and navigation structure.




22. Named Routes and Login Flow


Named routes can be used to organize a simple login flow.


Login Screen
     |
     | Navigator.pushReplacementNamed(context, '/home')
     ↓
Home Screen

Example


ElevatedButton(
  onPressed: () {
    Navigator.pushReplacementNamed(
      context,
      '/home',
    );
  },
  child: const Text('Login'),
)

pushReplacementNamed() replaces the current route with the named route so that the user does not return to the previous route through normal back navigation.




23. Removing Routes with pushNamedAndRemoveUntil()


pushNamedAndRemoveUntil() pushes a named route and removes previous routes according to a predicate.


Example


Navigator.pushNamedAndRemoveUntil(
  context,
  '/home',
  (route) => false,
);

This example navigates to /home and removes the previous routes from the stack.


This pattern may be used after logout, registration completion, or finishing a checkout flow where earlier screens should not remain accessible through back navigation.




24. Named Routes vs Direct Navigator.push()











FeatureNamed RoutesDirect Route Navigation
Navigation methodNavigator.pushNamed()Navigator.push()
Screen referenceUses a string route nameUses a route object and destination widget
Route configurationDefined centrallyUsually created at the navigation point
ReadabilityShort navigation statementsMore explicit route construction
ArgumentsPassed through arguments or route generationOften passed through a constructor
Dynamic routingMay require onGenerateRoute or another routing solutionCan directly construct a destination with required data
Current Flutter guidanceNot recommended for most new applicationsSuitable for simple navigation using Navigator and explicit routes



25. Advantages of Named Routes



  • Route names can make navigation code short and readable.

  • Routes can be configured in one central location.

  • The same route can be accessed from different parts of the application.

  • Named routes can reduce repeated route-building code.

  • They can be useful in small applications with a fixed set of screens.

  • They support passing arguments through the Navigator's route settings.




26. Limitations of Named Routes



  • Route names are strings, so spelling mistakes may cause navigation errors.

  • Arguments passed through arguments may require type casting.

  • Complex dynamic routes may require additional route-generation logic.

  • Basic named routes do not automatically provide a complete solution for advanced deep linking.

  • Large applications may require more structured routing solutions.

  • Flutter's current documentation does not recommend named routes for most applications.




27. Common Mistakes


Mistake 1: Using an Undefined Route Name


Navigator.pushNamed(context, '/unknown');

If /unknown is not configured and no suitable fallback is provided, navigation may fail or invoke route-generation fallback logic.


Mistake 2: Spelling Mistakes in Route Names


routes: {
  '/profile': (context) => const ProfileScreen(),
}

Navigator.pushNamed(context, '/profle');


The route names do not match. Use centralized constants to reduce this problem.


Mistake 3: Defining home and initialRoute Together


MaterialApp(
  home: const HomeScreen(),
  initialRoute: '/login',
);

Choose an appropriate starting-screen configuration instead of defining conflicting initial navigation settings.


Mistake 4: Incorrect Argument Type


final id = ModalRoute.of(context)!.settings.arguments as int;

If the caller passes a string or map instead of an integer, a runtime type error may occur. Ensure that the sender and receiver agree on the argument type.




28. Best Practices



  • Use meaningful route names such as /profile, /settings, and /product-details.

  • Keep route names in a centralized class or constants file.

  • Use consistent naming conventions throughout the project.

  • Validate route arguments before using them.

  • Use custom argument classes when multiple values must be passed together.

  • Provide an unknown-route fallback when appropriate.

  • Use pushReplacementNamed() when the current route should not remain in the navigation stack.

  • Use pushNamedAndRemoveUntil() when previous routes need to be removed.

  • For simple navigation, consider using Navigator.push() with MaterialPageRoute and constructor-based data passing.

  • For advanced navigation, deep linking, and complex route requirements, consider Router-based navigation or a routing package such as go_router.




29. When Should You Use Named Routes?


Named routes may be useful when:



  • The application has a small number of fixed screens.

  • Several widgets navigate to the same destination.

  • You want route names to be managed in one location.

  • The navigation flow is simple and does not require complex URL handling.


For new applications with advanced navigation requirements, evaluate Navigator with explicit routes, Router-based navigation, or a routing package such as go_router.




30. Interview Questions


Q1. What are named routes in Flutter?


Named routes are routes identified by unique string names. They allow navigation between screens using route names instead of creating a route object at every navigation point.


Q2. Where are named routes defined?


Named routes are commonly defined in the routes property of MaterialApp or CupertinoApp.


Q3. What is the use of Navigator.pushNamed()?


Navigator.pushNamed() opens a route by using its configured route name.


Q4. How do you close a named route?


Use Navigator.pop(context) to remove the current route and return to the previous screen.


Q5. What is the purpose of initialRoute?


initialRoute specifies the named route displayed when the application starts.


Q6. How do you pass arguments to a named route?


Pass data through the arguments parameter of Navigator.pushNamed().


Q7. How do you receive named route arguments?


Arguments can be accessed using ModalRoute.of(context)!.settings.arguments or through an onGenerateRoute callback.


Q8. What is onGenerateRoute?


onGenerateRoute is a callback used to create routes dynamically based on route settings.


Q9. What is the difference between pushNamed() and pushReplacementNamed()?


pushNamed() adds a new named route to the stack, while pushReplacementNamed() replaces the current route with a named route.


Q10. Are named routes recommended for every Flutter application?


No. Flutter's current documentation does not recommend named routes for most applications. The appropriate navigation approach depends on the application's requirements, including deep linking, URL synchronization, and routing complexity.




31. Practice Exercises



  1. Create a Flutter application with / and /details named routes.

  2. Use Navigator.pushNamed() to open the Details Screen.

  3. Use Navigator.pop() to return to the Home Screen.

  4. Create named routes for Home, Profile, and Settings screens.

  5. Store all route names in a separate AppRoutes class.

  6. Pass a product name through the arguments parameter.

  7. Receive the product name using ModalRoute.of(context).

  8. Create a custom argument class and pass it to a named route.

  9. Implement onGenerateRoute for three screens.

  10. Create a fallback screen using onUnknownRoute.

  11. Build a login flow using pushReplacementNamed().

  12. Build a logout flow using pushNamedAndRemoveUntil().




32. Quick Revision














ConceptCodePurpose
Define routesroutes: {}Map route names to screen builders
Set initial routeinitialRoute: '/'Choose the starting named route
Open named routeNavigator.pushNamed(context, '/profile')Navigate to a named screen
Close routeNavigator.pop(context)Return to the previous screen
Pass argumentsarguments: dataSend data to a named route
Read argumentsModalRoute.of(context)Access route arguments
Generate routesonGenerateRouteCreate routes dynamically
Handle unknown routesonUnknownRouteDisplay a fallback route
Replace routepushReplacementNamed()Replace the current route
Clear route historypushNamedAndRemoveUntil()Push a route and remove previous routes



33. Key Takeaways



  • Named routes identify screens using string names.

  • Named routes are configured using the routes property.

  • initialRoute determines the starting named route.

  • Navigator.pushNamed() opens a named route.

  • Navigator.pop() closes the current route.

  • Arguments can be passed using the arguments parameter.

  • Arguments can be received through ModalRoute.of(context) or onGenerateRoute.

  • Route constants help prevent spelling mistakes.

  • onGenerateRoute supports custom route-generation logic.

  • onUnknownRoute can provide a fallback screen.

  • pushReplacementNamed() replaces the current route.

  • pushNamedAndRemoveUntil() can remove previous routes.

  • Named routes are not recommended for most new applications according to current Flutter documentation.

  • For advanced navigation and deep-linking requirements, consider Router-based navigation or a routing package such as go_router.




34. Official Flutter Documentation





35. Flutter Training Resources


For more information about Flutter development and training, visit the following resources:



whatsapp