navigation_devtools 0.1.0
navigation_devtools: ^0.1.0 copied to clipboard
Flutter DevTools extension for navigation — inspect the live backstack of Navigator 1.0, Router API, go_router, or auto_route apps, and navigate interactively.
navigation_devtools #
A Flutter DevTools panel for inspecting and driving navigation in any Flutter app: live backstack, declared route tree, per-route args/params, and confirm-gated interactive navigation.
This is the core package. It contains:
- the prebuilt DevTools panel (an
extension/devtools/bundle DevTools discovers automatically), - the
NavigationAdapterAPI that routing systems plug into, - two dependency-free adapters: Navigator 1.0 and generic
RouterDelegate, - an adapter conformance test kit (
package:navigation_devtools_test/navigation_devtools_test.dart).
Router-specific adapters live in their own packages so your app only depends on what it uses: go_router_devtools, auto_route_devtools. Depending on any adapter package transitively includes this panel.
Navigator 1.0 apps #
Flutter offers no API to read a Navigator's stack, so the adapter observes mutations and maintains a shadow stack. Attach its observer to exactly one navigator:
import 'package:navigation_devtools/navigation_devtools.dart';
final Map<String, WidgetBuilder> appRoutes = {
'/': (_) => const HomeScreen(),
'/details': (_) => const DetailsScreen(),
};
void main() {
final adapter = Navigator1Adapter(routes: appRoutes);
NavigationDevTools.register(adapter);
runApp(MaterialApp(
routes: appRoutes,
navigatorObservers: [adapter.observer],
));
}
- Passing your
routes:map unlocks the route-table pane and path/name navigation; without it the adapter can still show the live stack and pop. onGenerateRoutefactories are opaque code and cannot be enumerated.- Anonymous
Navigator.push(MaterialPageRoute(...))entries — including dialogs and bottom sheets (showDialog,showModalBottomSheet) — appear with apagelessbadge and a synthesized name (DialogRoute<void>,ModalBottomSheetRoute<void>), and can be popped from the panel. - Nested
Navigators: register one adapter per navigator (aNavigatorObservercan only observe one); the panel shows them in its router selector.
Custom RouterDelegate apps (Navigator 2.0) #
final delegate = AppRouterDelegate();
NavigationDevTools.register(
RouterDelegateAdapter(delegate, parser: AppRouteParser()),
);
runApp(MaterialApp.router(
routerDelegate: delegate,
routeInformationParser: AppRouteParser(),
));
The Router API exposes only currentConfiguration, so the panel shows a single synthesized frame (type, toString() preview, and — with the parser — the restored URL). Passing the parser also enables navigate-by-path from the panel. For a full-fidelity stack, additionally attach a Navigator1Adapter().observer to the Navigator your delegate builds and register that adapter too.
Release builds #
Everything is a hard no-op under kReleaseMode: no service extensions are registered and adapters cost nothing.
Writing an adapter for another router #
Implement NavigationAdapter (id/kind/label, capabilities, describeRoutes, currentStack, navigate, changes) and register instances with NavigationDevTools.register. Contract essentials:
- Advertise only capabilities that work; non-advertised actions must return
NavigateResult(ok: false, ...), never throw. - Never await pop-completing futures in
navigate()—Navigator.pushNamed, go_routerpush, and friends only complete when the pushed route is popped. Dispatch, then return.
Then prove it with the conformance kit in your tests:
import 'package:navigation_devtools_test/navigation_devtools_test.dart';
void main() {
runAdapterConformanceTests(
'MyAdapter',
AdapterHarness(
setUp: (tester) async { /* pump app, return adapter */ },
performNavigation: (tester) async { /* stack a route in-app */ },
navigableTestPath: '/details/9',
),
);
}
The kit asserts identity stability, non-throwing serialization, change notifications, and that every advertised capability actually works.
Known limitations #
- Route arguments are arbitrary Dart objects; the panel shows
runtimeType+toString()previews. - The panel bundle is prebuilt; contributors rebuild it with
dart run devtools_extensions build_and_copyfrom thenavigation_devtools_extensionpackage in the repo.