A Flutter learning repository focused on understanding GoRouter and navigation in real-world Flutter applications.
This repository documents my progress while learning different GoRouter concepts, starting from basic routing and gradually moving toward advanced navigation patterns such as nested routes, redirects, StatefulShellRoute, route observers, navigation keys, and stack management.
Learned how to:
- Add and configure GoRouter in a Flutter application.
- Create the first
GoRouterinstance. - Define routes using
GoRoute. - Navigate between different screens.
- Understand the basic structure of a GoRouter-based application.
Learned how to pass dynamic values through the URL/path.
Example:
/users/:id
And retrieve the parameter from the route:
final id = state.pathParameters['id'];This is useful for pages such as:
- User details
- Product details
- Post details
- Profile pages
Learned how to pass complete Dart objects between screens using GoRouter.
This helped me understand the difference between:
- Passing data through the URL/path.
- Passing an object directly through route navigation.
Learned how to create routes inside other routes.
Example:
/users
/users/:id
/users/:id/details
This is useful for building hierarchical navigation structures.
Learned how GoRouter's redirect mechanism can control where the user is allowed to navigate.
For example:
User opens protected page
↓
Check authentication
↓
Logged in? ── Yes ──> Protected page
│
No
↓
Login page
This can be used for:
- Authentication
- Onboarding
- Login flows
- Protected routes
- Conditional navigation
Integrated Riverpod with GoRouter to make routing depend on application state.
I learned how to use application state such as:
isLogin
isFirst
inside router redirect logic.
This helped me understand how navigation can react to changes in application state.
Learned how refreshListenable can tell GoRouter to reevaluate its routing logic when a listened-to value changes.
I also created a GoRouteNotifier to connect application state changes with GoRouter.
Conceptually:
Application State Changes
↓
GoRouteNotifier
↓
refreshListenable
↓
GoRouter refreshes
↓
redirect()
This is particularly useful for authentication and onboarding state.
Learned how to use StatefulShellRoute for applications with persistent navigation branches.
Implemented navigation patterns including:
- Bottom navigation
- Tab navigation
- Drawer navigation
- Multiple navigation branches
The important concept I learned is that each branch can maintain its own navigation state.
For example:
StatefulShellRoute
│
┌────────┼────────┐
↓ ↓ ↓
Home Search Profile
│ │ │
Stack A Stack B Stack C
Switching between branches can preserve the navigation state of each branch.
Learned how StatefulNavigationShell.goBranch() works with bottom navigation.
I also explored the behavior of:
initialLocationwhen switching branches.
This helped me understand the difference between:
- Returning to the branch's initial route.
- Restoring the branch's previous navigation state.
Learned how to use different NavigatorKeys with GoRouter.
One use case I implemented was controlling whether a bottom navigation bar should appear for certain routes.
Conceptually:
Root Navigator
│
├── Bottom Navigation Routes
│
└── Detail Routes
This helped me understand how multiple navigator stacks can be used to create more complex navigation structures.
Learned how to handle unknown or invalid routes.
Implemented an error screen for situations where the requested path does not exist.
Example:
Unknown URL
↓
GoRouter
↓
Error Handling
↓
Error Screen
This prevents the application from failing silently when a user navigates to an invalid path.
Learned how to use pageBuilder to control page transitions.
I experimented with:
- Removing the default transition.
- Adding custom page transitions.
- Controlling how a new page enters the screen.
Example:
pageBuilder: (context, state) {
return CustomTransitionPage(
child: MyScreen(),
transitionsBuilder: ...,
);
}This gives more control over the navigation experience than simply using the default route behavior.
Learned how to use a RouteObserver with GoRouter to observe navigation lifecycle events.
Used it in a details screen to understand when a route:
- Is pushed.
- Becomes visible.
- Is covered by another route.
- Becomes visible again.
This helped me understand the relationship between navigation and Flutter widget lifecycle.
Learned about a common navigation problem where repeatedly navigating to the same screen can push multiple copies of that screen onto the navigation stack.
For example:
Home
↓
Details
↓
Details
↓
Details
Instead of allowing unnecessary duplicate screens, I implemented logic to prevent the same screen from repeatedly being pushed.
I also created an extension to make this behavior easier to reuse.
| Concept | Learned |
|---|---|
| GoRouter Setup | ✅ |
| Basic Routes | ✅ |
| Path Parameters | ✅ |
| Passing Objects | ✅ |
| Sub-Routes | ✅ |
| Redirects | ✅ |
| Riverpod Integration | ✅ |
refreshListenable |
✅ |
GoRouteNotifier |
✅ |
StatefulShellRoute |
✅ |
| Bottom Navigation | ✅ |
| Tab Navigation | ✅ |
| Drawer Navigation | ✅ |
goBranch() |
✅ |
initialLocation |
✅ |
| Navigator Keys | ✅ |
| Error Routes | ✅ |
| Custom Page Transitions | ✅ |
pageBuilder |
✅ |
| Route Observer | ✅ |
| Navigation Lifecycle | ✅ |
| Navigation Stack Management | ✅ |
| Reusable Navigation Extensions | ✅ |
Throughout this repository, I gradually moved from simple routing to a more realistic application navigation structure:
GoRouter
│
┌─────────┴─────────┐
│ │
Redirects Navigation
│ │
┌─────┴─────┐ ┌─────┴──────────┐
│ │ │ │
Auth State Onboarding Routes StatefulShellRoute
│ │ │
Riverpod Sub-Routes Navigation Branches
│ │ │
refreshListenable Parameters Bottom Navigation
│ │
Objects Navigator Keys
The main thing I learned from this repository is that GoRouter is more than just a replacement for basic Navigator.push() calls.
It can be used to build a structured navigation system that handles:
- Application state
- Authentication
- Deep linking
- Nested navigation
- Persistent navigation branches
- Bottom navigation
- Route lifecycle
- Custom transitions
- Error handling
- Navigation stack management
The repository is a practical record of my learning journey from basic GoRouter setup to more advanced navigation architecture.
Basic Routing
↓
Path Parameters
↓
Objects & Sub-Routes
↓
Redirects
↓
Riverpod Integration
↓
refreshListenable
↓
StatefulShellRoute
↓
Bottom Navigation
↓
Navigator Keys
↓
Error Handling
↓
Custom Transitions
↓
Route Observer
↓
Navigation Stack Management
GitHub: RadheAnkit01/go_router_flutter
This repository is primarily a learning project where I experiment with GoRouter concepts, test navigation behavior, and build small implementations to understand how Flutter navigation works internally.