DEV Community

Twilight
Twilight

Posted on

Best Practices for Managing Route Names and Paths with go_router in Flutter

Are you tired of typing out long, hard-coded paths when navigating between screens in your Flutter app? Or worried about circular imports while organizing your routes across multiple features? In this post, we’ll explore how to manage route names and paths using go_router in a clean and maintainable way.


1. Why Avoid Hard-Coding Routes?

Using strings like context.go("/some/really/long/path/42") all over your codebase can be error-prone and difficult to maintain. If you ever decide to change "/some/really/long/path" to "/shorter/path", you’ll have to hunt down every place that calls it.

Instead, define named routes or centralized route constants. This helps you:

  • Avoid typos.
  • Keep the code DRY (Don’t Repeat Yourself).
  • Make future changes to your routes simpler.

2. Named Routes in go_router

go_router lets you define both a path and a name for your routes. You can then call context.goNamed() instead of context.go().

Here’s a quick example:

import 'package:go_router/go_router.dart';

final router = GoRouter(
  routes: [
    GoRoute(
      name: 'home',
      path: '/home',
      builder: (context, state) => const HomePage(),
    ),
    GoRoute(
      name: 'profile',
      path: '/profile/:userId',
      builder: (context, state) {
        final userId = state.pathParameters['userId'];
        return ProfilePage(userId: userId);
      },
    ),
  ],
);

// Navigate by route name
context.goNamed('profile', params: {'userId': '42'});
Enter fullscreen mode Exit fullscreen mode

With named routes:

  • If you rename /profile/:userId to /users/:id, you only update one place (the route definition) instead of every go() call in the project.

3. Centralizing Route Names and Paths

Create a file or class that contains all of your route constants. For example:

// app_routes.dart
abstract class AppRouteName {
  static const home = 'home';
  static const profile = 'profile';
}

abstract class AppRoutePath {
  static const home = '/home';
  static const profile = '/profile/:userId';
}
Enter fullscreen mode Exit fullscreen mode

Then, when defining routes:

GoRoute(
  name: AppRouteName.profile,
  path: AppRoutePath.profile,
  builder: (context, state) => ...
);
Enter fullscreen mode Exit fullscreen mode

And when navigating:

context.goNamed(
  AppRouteName.profile,
  params: {'userId': '42'},
);
Enter fullscreen mode Exit fullscreen mode

This approach makes it easy to manage changes in path structure and ensures a single source of truth for route definitions.


4. Organizing Routes in Larger Apps

If you’re following a feature-first approach:

  1. Core Layer: Defines shared resources, services, or base classes.
  2. Feature Layer: Each feature can define its own UI, logic, and route definitions.
  3. App (Composition) Layer: Imports both the core and the features, then merges all routes in one central GoRouter.

This avoids circular imports:

  • Core doesn’t import features.
  • Features import core if needed.
  • App imports both core and features to assemble the final routes.

A typical folder structure might look like this:

lib/
 ├── core/
 |    └── app_routes.dart
 ├── features/
 |    ├── feature_a/
 |    └── feature_b/
 └── app/
      ├── app_router.dart
      └── main.dart
Enter fullscreen mode Exit fullscreen mode

The app_router.dart then gathers routes from core and each feature, creating one unified router.


5. Final Tips

  • Use go_router_builder if you want generated, type-safe route navigation functions like context.goToProfile(userId: 42).
  • Keep route definitions minimal and avoid burying complex logic within them.
  • For dynamic screens, leverage pathParameters or queryParameters to parse IDs and flags.

By following these best practices—named routes, centralized constants, and a layered architecture—you’ll save yourself tons of headaches and ensure a more maintainable Flutter codebase. Happy coding!

Image of Datadog

How to Diagram Your Cloud Architecture

Cloud architecture diagrams provide critical visibility into the resources in your environment and how they’re connected. In our latest eBook, AWS Solution Architects Jason Mimick and James Wenzel walk through best practices on how to build effective and professional diagrams.

Download the Free eBook

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more