Routing System (GoRouter)
Relevant source files
The following files were used as context for generating this wiki page:
The Routing System in MoodTune is built using the go_router package, providing a declarative and type-safe navigation framework for the Flutter mobile application. It is designed to handle complex navigation patterns, including authentication-aware redirects, tab-based navigation via shell routes, and deep linking. The system is integrated with the project's Clean Architecture, ensuring a clear separation between route definitions and UI implementation.
The primary goal of the system is to centralize navigation logic, manage authentication states reactively, and provide a robust error handling mechanism for invalid routes. It supports both guest and authenticated flows, directing users to appropriate entry points like /onboarding for new users or /home for authenticated users.
Sources: routing_plan.md:15-30, CLAUDE.md:76-78, README.md:23-35
Architecture Overview
The architecture follows a hierarchical structure where the MaterialApp.router utilizes a centralized AppRouter configuration. This configuration defines the route tree, manages redirects based on authentication state, and handles global errors.
Component Hierarchy
The diagram above illustrates the relationship between the root application widget, the central router configuration, and the specialized shell routes for tab navigation.
Sources: routing_plan.md:28-48, CLAUDE.md:36-39
Core Components
Route Configuration
The routing system is organized into three primary files located in lib/core/routing/:
app_router.dart: Contains the mainGoRouterinstance and logic.route_names.dart: Defines type-safe constants for all application paths.dialog_utils.dart: Provides helper methods for non-route navigation elements like snackbars and dialogs.
| Component | Responsibility | Source |
|---|---|---|
| GoRouter | Declarative API for Navigator 2.0 | pubspec.yaml:31 |
| RouteNames | Centralized string constants to prevent typos | routing_plan.md:82-108 |
| AppRouter | Single instance managing routes, redirects, and errors | routing_plan.md:118-135 |
| RefreshListenable | Reactive bridge between Auth stream and Router | routing_plan.md:287-308 |
Route Names and Path Patterns
Type safety is enforced through the RouteNames class, which uses static constants and helper methods for routes requiring path parameters.
class RouteNames {
static const String initial = '/';
static const String onboarding = '/onboarding';
static const String waitTimeDetails = '/wait-times/:id';
static String waitTimeDetailsRoute(String id) {
return waitTimeDetails.replaceAll(':id', id);
}
}
Sources: routing_plan.md:94-108, routing_plan.md:546-557
Navigation Logic and Data Passing
Navigation Patterns
MoodTune utilizes specific go_router methods depending on the desired navigation behavior:
- push: Adds a route to the stack, allowing back navigation. Used for detail pages and forms.
- go: Replaces the entire stack. Used for authentication state changes and primary tab switches.
- pop: Returns to the previous screen, optionally passing data back.
Sources: routing_plan.md:224-266, routing_plan.md:468-477
Data Transfer
The system supports three methods for passing data between screens:
- Path Parameters: Required identifiers (e.g.,
:id) embedded in the URL. - Query Parameters: Optional filters or search queries (e.g.,
?q=search). - Extra Data: Complex objects passed via
state.extra. Note thatextrais dynamic and requires casting upon arrival.
Sources: routing_plan.md:154-183, CLAUDE.md:77-78
Authentication-Aware Routing
The routing system is intrinsically linked to the SupabaseAuthService. It uses a refreshListenable to monitor authentication state changes reactively.
Authentication Flow
This sequence shows how the application automatically reacts to login events without manual imperative calls.
Sources: routing_plan.md:290-320, authplan.md:195-200
Redirect Logic Implementation
The redirect callback acts as a global guard. It evaluates two primary conditions on every navigation event:
- Unauthenticated Users: If the user is not logged in and attempts to access a protected route, they are redirected to
/onboarding. - Authenticated Users: If a logged-in user attempts to access public routes (like
/login), they are redirected to the home screen.
Sources: routing_plan.md:323-352, routing_plan.md:568-586
Shell Routing (Tab Navigation)
For the main application interface, MoodTune uses StatefulShellRoute.indexedStack. This allows for a persistent bottom navigation bar where each tab (Home, History) maintains its own independent navigation stack and scroll position.
Tab Branch Architecture
Each branch operates as an independent navigator, ensuring that navigating deep into one tab does not affect the state of another.
Error Handling
Global error handling is managed via the errorBuilder property in the GoRouter configuration. This ensures that any navigation to a non-existent route (404) or a routing failure displays a user-friendly ErrorPage.
Error Handling Features
- Global Catch: Captures all routing exceptions.
- Contextual Feedback: Displays the specific error message when available.
- Recovery Options: Typically provides a "Go Home" button to reset the application state.
Sources: routing_plan.md:428-448, routing_plan.md:588
Summary
The Routing System in the MoodTune app provides a centralized, reactive, and type-safe infrastructure for navigating between features. By leveraging GoRouter's declarative nature and integrating it with Supabase's authentication stream, the app ensures that users are always directed to the correct context based on their session status. The use of shell routes further enhances the user experience by preserving state across primary application sections like Home and History.
Sources: routing_plan.md:650-658, CLAUDE.md:36-39