Drive Navigator 2.0 from state.

declarative_nav lets you manage pages and overlays as plain state without directly calling Navigator.push/pop or showDialog.

Pages as Data

PageEntry does not hold Widget types. UI is constructed through your resolver callback.

Screen-local Overlays

Dialogs and sheets can be scoped by screen, including tab-local state when needed.

State-management Agnostic

Works with setState, Riverpod, Bloc, Provider, or any other state layer.

Getting Started Flow

Install the package, then move pages and overlays into explicit state.

Installation

flutter pub add declarative_nav

Starter Shape

app_root.dart
class AppRootState extends State<AppRoot> {
  OverlayRequest? _overlay;
  late List<PageEntry> _pages;

  @override
  void initState() {
    super.initState();
    _pages = const [PageEntry(key: 'home', name: '/home')];
  }

  Widget build(BuildContext context) {
    return DeclarativePagesNavigator(
      pages: _pages,
      buildPage: _buildPage,
      onPopTop: _popTop,
      canPopTop: () => _overlay == null,
    );
  }
}
Core Rule

Do not mix imperative push/pop and declarative List<PageEntry> for the same stack. Keeping one source of truth prevents navigation drift.

Previous

OSS