Menu

Routing and Navigation

Relevant source files

This document describes the routing and navigation system in the Flutter Mobile Project Template. The template uses go_router with typesafe routes to handle application navigation, including normal routes, shell routes for persistent navigation elements, and special routes for maintenance and debug modes.

Router Configuration

The application's routing is configured using a Riverpod provider that exposes a GoRouter instance. The router handles navigation between different screens and implements conditional logic for special states like maintenance mode.

Sources: apps/app/lib/router/router.dart26-52 apps/app/lib/router/router.g.dart11-173

The router is defined in the routerProvider, which is a Riverpod provider annotated with @Riverpod(keepAlive: true) to ensure it remains active throughout the application lifecycle. The router watches the maintenance mode state and redirects to the maintenance page when necessary:

Sources: apps/app/lib/router/router.dart26-52 apps/app/lib/main.dart43-46

Route Structure

The application uses a hierarchical route structure with typed routes generated using the go_router package's code generation feature.

Sources: apps/app/lib/router/router.g.dart11-173

The routes are organized into several categories:

  1. Main application shell - Handles the bottom navigation tabs using StatefulShellRoute

    • Home branch (/)
    • Settings branch (/setting) with nested routes:
      • License page (/setting/license)
  2. Special routes

    • Maintenance page (/maintenance) - Shown when the app is in maintenance mode
    • Debug page (/debug) - Only available in debug mode
  3. Debug-specific routes

    • Navigation debug page (/debug/navigation_debug) - For testing navigation functionality

Sources: apps/app/lib/router/routes/main/main_page_shell_route.dart apps/app/lib/router/routes/main/home/home_shell_branch.dart apps/app/lib/router/routes/main/setting/setting_shell_branch.dart apps/app/lib/router/routes/maintenance_page_route.dart apps/app/lib/router/routes/main/home/debug_page_route.dart

Route Implementation with GoRouterData

The application uses a typesafe approach to defining routes by extending GoRouteData classes, combined with code generation to create route helpers.

Sources: apps/app/lib/router/routes/main/home/home_shell_branch.dart15-34 apps/app/lib/router/routes/main/setting/setting_shell_branch.dart29-58 apps/app/lib/router/routes/maintenance_page_route.dart3-17 apps/app/lib/router/routes/main/main_page_shell_route.dart3-20

Each route class provides a build method that returns the Widget to display for that route. The annotation-based approach combined with code generation creates extension methods for each route class that provide typesafe navigation:

MethodDescription
locationReturns the string path for the route
go(context)Navigates to the route, replacing the current history entry
push<T>(context)Pushes the route onto the navigator stack
pushReplacement(context)Pushes the route and removes the previous route from the stack
replace(context)Replaces the current route

Sources: apps/app/lib/router/router.g.dart99-114 apps/app/lib/router/router.g.dart116-132

Shell Routes for Bottom Navigation

The application uses StatefulShellRoute to implement bottom navigation with persistent tab state. The main page shell encapsulates two branches: home and settings.

Sources: apps/app/lib/router/routes/main/main_page_shell_route.dart3-20 apps/app/lib/router/routes/main/home/home_shell_branch.dart3-13 apps/app/lib/router/routes/main/setting/setting_shell_branch.dart3-18

The MainPageShellRoute provides the container for the bottom navigation, while each branch contains the routes for a specific tab. The pattern allows for maintaining state between tab switches and supporting nested navigation within each tab.

Feature-Specific Navigation

The template implements feature-specific navigation interfaces that are injected using Riverpod providers. This approach decouples the navigation logic from the UI components.

For example, the settings page uses a navigator interface to handle navigation to the license page:

Sources: apps/app/lib/router/routes/main/setting/setting_shell_branch.dart20-27 apps/app/lib/router/routes/main/setting/setting_shell_branch.dart34-44

Special Routes and Conditional Navigation

The template includes special routing behavior for maintenance mode and debug functionality:

  1. Maintenance Mode: A global redirect that checks the maintenance mode state and redirects all navigation to the maintenance page when enabled
  2. Debug Routes: Routes that are only included in debug builds

Sources: apps/app/lib/router/router.dart32-39 apps/app/lib/router/router.dart43-50

The debug page route also includes a special keyboard shortcut for quick access during development:

Sources: apps/app/lib/main.dart87-103

Integrating the Router with the Application

The router is integrated into the application in the MainApp widget using the MaterialApp.router constructor, which delegates all navigation to the GoRouter:

Sources: apps/app/lib/main.dart39-105

This setup allows the application to handle routing while still using Material Design components and theming.

Conclusion

The routing system in the Flutter Mobile Project Template provides a typesafe, maintainable approach to navigation with support for nested routes, bottom navigation tabs, and special application states like maintenance mode. The use of GoRouter with code generation and Riverpod for dependency injection creates a clean separation of concerns between navigation logic and UI components.