why you choose go router then the navigator 2.0 ? what are all the additional functionality go router have then the navigator 2.0 ?

#route#go_router#navigator#navigation

Answer

Overview

text
go_router
is a declarative routing package built on top of Navigator 2.0 that simplifies complex navigation scenarios. While Navigator 2.0 provides powerful low-level APIs,
text
go_router
offers a developer-friendly abstraction with additional features that make it the preferred choice for most applications.

Comparison Table

FeatureNavigator 2.0go_router
Learning CurveSteep, complexBeginner-friendly
Boilerplate CodeHighMinimal
Deep LinkingManual setupBuilt-in
URL-based NavigationRequires custom implementationNative support
RedirectionManual implementationBuilt-in redirect API
Named RoutesYesYes, path-based
Query ParametersManual parsingBuilt-in support
Path ParametersManual parsingBuilt-in support
Nested NavigationComplex setupSimple, declarative
Web SupportGoodExcellent
Type SafetyManualBetter with extensions
Error HandlingCustomBuilt-in error page
Authentication GuardsManualBuilt-in redirect logic

Why Choose go_router Over Navigator 2.0

1. Simplified API

Navigator 2.0 requires implementing

text
RouterDelegate
,
text
RouteInformationParser
, and managing pages manually. go_router handles this complexity internally.

Navigator 2.0:

dart
// Requires extensive boilerplate
class MyRouterDelegate extends RouterDelegate<MyRoutePath>
    with ChangeNotifier, PopNavigatorRouterDelegateMixin<MyRoutePath> {
  
  final GlobalKey<NavigatorState> navigatorKey;
  
  // Complex state management
  List<Page> _pages = [];
  
  
  Widget build(BuildContext context) {
    return Navigator(
      key: navigatorKey,
      pages: _pages,
      onPopPage: (route, result) {
        // Manual pop handling
      },
    );
  }
  
  
  Future<void> setNewRoutePath(MyRoutePath path) async {
    // Manual path parsing
  }
}

class MyRouteInformationParser extends RouteInformationParser<MyRoutePath> {
  
  Future<MyRoutePath> parseRouteInformation(
      RouteInformation routeInformation) async {
    // Manual URL parsing
  }
}

go_router:

dart
final GoRouter router = GoRouter(
  routes: [
    GoRoute(
      path: '/',
      builder: (context, state) => HomeScreen(),
    ),
    GoRoute(
      path: '/details/:id',
      builder: (context, state) {
        final id = state.pathParameters['id']!;
        return DetailsScreen(id: id);
      },
    ),
  ],
);

2. Built-in Deep Linking

go_router automatically handles deep links without additional setup.

dart
final router = GoRouter(
  routes: [
    GoRoute(
      path: '/products/:categoryId/items/:itemId',
      builder: (context, state) {
        final categoryId = state.pathParameters['categoryId']!;
        final itemId = state.pathParameters['itemId']!;
        return ProductDetailScreen(
          categoryId: categoryId,
          itemId: itemId,
        );
      },
    ),
  ],
);

// Deep link: myapp://products/electronics/items/123
// Automatically parsed and routed

3. Authentication & Redirection

go_router provides built-in redirect functionality for authentication flows.

dart
final router = GoRouter(
  redirect: (context, state) {
    final isLoggedIn = authService.isAuthenticated();
    final isLoggingIn = state.matchedLocation == '/login';
    
    // Redirect to login if not authenticated
    if (!isLoggedIn && !isLoggingIn) {
      return '/login';
    }
    
    // Redirect to home if already logged in
    if (isLoggedIn && isLoggingIn) {
      return '/';
    }
    
    return null; // No redirect needed
  },
  routes: [
    GoRoute(
      path: '/',
      builder: (context, state) => HomeScreen(),
    ),
    GoRoute(
      path: '/login',
      builder: (context, state) => LoginScreen(),
    ),
  ],
);

4. Query Parameters Support

dart
// Navigate with query parameters
context.go('/search?q=flutter&sort=date');

// Access in route
GoRoute(
  path: '/search',
  builder: (context, state) {
    final query = state.uri.queryParameters['q'] ?? '';
    final sort = state.uri.queryParameters['sort'] ?? 'relevance';
    return SearchScreen(query: query, sort: sort);
  },
),

5. Nested Navigation (Shell Routes)

go_router makes nested navigation simple with

text
ShellRoute
.

dart
final router = GoRouter(
  routes: [
    ShellRoute(
      builder: (context, state, child) {
        return ScaffoldWithNavBar(child: child);
      },
      routes: [
        GoRoute(
          path: '/home',
          builder: (context, state) => HomeScreen(),
        ),
        GoRoute(
          path: '/profile',
          builder: (context, state) => ProfileScreen(),
        ),
      ],
    ),
  ],
);

6. Error Handling

dart
final router = GoRouter(
  errorBuilder: (context, state) => ErrorScreen(
    error: state.error,
  ),
  routes: [
    // routes
  ],
);

7. Refresh Listener

go_router can rebuild routes when app state changes.

dart
final router = GoRouter(
  refreshListenable: authChangeNotifier,
  routes: [
    // Routes automatically refresh when auth state changes
  ],
);

Additional Functionalities in go_router

1. Named Location Extension

dart
extension on GoRouter {
  void goHome() => go('/');
  void goProfile(String userId) => go('/profile/$userId');
}

2. Transition Animations

dart
GoRoute(
  path: '/details',
  pageBuilder: (context, state) => CustomTransitionPage(
    child: DetailsScreen(),
    transitionsBuilder: (context, animation, secondaryAnimation, child) {
      return FadeTransition(
        opacity: animation,
        child: child,
      );
    },
  ),
),

3. Path Pattern Matching

dart
GoRoute(
  path: '/users/:userId(\\d+)', // Only matches numeric IDs
  builder: (context, state) => UserScreen(),
),

4. Wildcard Routes

dart
GoRoute(
  path: '/files/:path(.*)', // Matches any path
  builder: (context, state) {
    final path = state.pathParameters['path']!;
    return FileViewer(path: path);
  },
),

5. Extra Parameters

dart
// Pass complex objects
context.go('/details', extra: productObject);

// Access in route
GoRoute(
  path: '/details',
  builder: (context, state) {
    final product = state.extra as Product;
    return DetailsScreen(product: product);
  },
),

When to Use Each

Use Navigator 2.0 When:

  • You need absolute control over navigation stack
  • Building highly custom navigation patterns
  • You have very specific requirements not covered by go_router
  • Working on a small app with simple navigation

Use go_router When:

  • Building web applications with URL-based routing
  • Need deep linking support
  • Implementing authentication flows
  • Want less boilerplate code
  • Need query parameters and path parameters
  • Building production apps (recommended by Flutter team)
  • Want better developer experience

Official Recommendation

Flutter's official documentation recommends using routing packages like go_router for applications with advanced navigation and routing requirements, especially for web apps that use direct links to each screen.

Best Practices

  • Use go_router for most production apps
  • Define routes in a separate file for maintainability
  • Implement type-safe routes using code generation
  • Use redirect for authentication guards
  • Leverage ShellRoute for persistent UI elements
  • Handle errors gracefully with errorBuilder

Official Documentation