Flutter GoRouter Extension
A Flutter package that extends go_router with Android-style navigation behaviors.
Features
isCurrent: Returns true if the currentBuildContextbelongs to the top-most route in the navigation stack.pushAndRemoveUntil: Simulates Android'sFLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_NEW_TASKbehaviorpopUntil: Pop routes until a specific route is reached, preserving the existing instancepopToRoot: Pop all routes until the root route is reached.ShellTabVisibilityDetector: Provides visibility callbacks for tabs inside aStatefulShellRoute.- Supports dynamic route parameters (e.g.,
/user/:id) - Supports wildcard routes (e.g.,
/files/*)
Installation
Add this to your pubspec.yaml:
dependencies:
flutter_go_router_extension: ^1.4.0
Usage
ShellTabVisibilityDetector
Tracks when nested tabs managed by a go_router StatefulShellRoute become visible or invisible.
// Wrap your tab's root widget
ShellTabVisibilityDetector(
onVisible: () => print('Tab is visible'),
onInVisible: () => print('Tab is hidden'),
child: const MyTabPage(),
)
Because go_router retains the state of StatefulShellBranch tabs in the background, standard RouteObserver fails to detect tab switching. This widget intelligently binds to Flutter's native TickerMode to provide completely accurate visibility events.
isCurrent
Returns true if the current BuildContext belongs to the top-most route in the navigation stack.
// In your widget
if (context.isCurrent) {
// Do something only if this is the active screen
}
popToRoot
Pops all routes from the navigator stack until the root route (/) is reached.
// In your widget
ElevatedButton(
onPressed: () {
context.popToRoot();
},
child: Text('Pop to Root'),
)
pushAndRemoveUntil
When navigating to a page that already exists in the stack, it clears all pages above and including that page, then pushes a new instance of the target page.
popUntil
Pops routes from the stack until a route matching the target URL is found, preserving the existing instance of that route (state, scroll position, and parameters are all retained).
Unlike pushAndRemoveUntil, this method does not create a new page instance—it simply removes the routes above the matching one.
import 'package:flutter_go_router_extension/flutter_go_router_extension.dart';
// In your widget
ElevatedButton(
onPressed: () {
context.popUntil('/user/123');
},
child: Text('Back to User'),
)
Comparison with pushAndRemoveUntil:
| Method | Matching route instance |
|---|---|
pushAndRemoveUntil(url) |
New instance (state reset) |
popUntil(url) |
Existing instance (state preserved) |
If the target URL is not found in the stack, the method does nothing.
import 'package:flutter_go_router_extension/flutter_go_router_extension.dart';
// In your widget
ElevatedButton(
onPressed: () {
context.pushAndRemoveUntil('/user/123');
},
child: Text('Go to User'),
)
Example
If the original stack is:
/home -> /user/123 -> /user/123/posts -> /comments
And you call:
context.pushAndRemoveUntil('/user/123');
Processing steps:
- Route
/user/:idconverts to RegExp:^/user/[^/]+$ - Check
/comments- No match, remove - Check
/user/123/posts- No match, remove - Check
/user/123- Match found
Resulting stack:
/home -> /user/123 (new instance)
How It Works
- Path to Regex Conversion: Dynamic parameters (
:param) are converted to[^/]+, wildcards (*) to.* - Stack Traversal: Iterates from the top of the navigation stack
- Match & Clear: When a matching route is found, all routes above it (including itself) are removed
- Push New Instance: A fresh instance of the target page is pushed onto the stack
Requirements
- Flutter SDK
- go_router: ^14.0.0 or higher
License
This project is licensed under the MIT License - see the LICENSE file for details.