Learn
Modules, tabs, and nested navigation
Let features own routes while each application chooses placement, Navigator scopes, and retained tab stacks.
v1.1.0Intermediate
Modules, tabs, and nested navigation
A Module answers “which routes belong to this feature?” A Mount answers “where does this application place that feature?” A Scope owns one Navigator stack.
A feature exports a Module
dart
NavigationModule createCatalogModule() => NavigationModule(
id: const NavigationModuleId('catalog'),
routes: <NavigationRouteDefinitionBase>[
catalogRoute,
productRoute,
],
);
The feature does not know whether it appears at /catalog, /shop, in one app, or in two shells.
The app mounts it
dart
NavigationMount(
id: const NavigationMountId('customer-catalog'),
moduleId: const NavigationModuleId('catalog'),
scopeId: const NavigationScopeId('catalog-tab'),
pathPrefix: '/catalog',
)
Each tab gets its own Scope
dart
scopes: const <NavigationScopeDefinition>[
NavigationScopeDefinition(id: NavigationScopeId('root')),
NavigationScopeDefinition(
id: NavigationScopeId('shell'),
parentId: NavigationScopeId('root'),
),
NavigationScopeDefinition(
id: NavigationScopeId('catalog-tab'),
parentId: NavigationScopeId('shell'),
),
NavigationScopeDefinition(
id: NavigationScopeId('profile-tab'),
parentId: NavigationScopeId('shell'),
),
],
Render the selected child stack:
dart
const NavigationActiveOutlet(parentScopeId: NavigationScopeId('shell'))
Switch tabs without destroying either stack:
dart
navigation.activateBranch(const NavigationScopeId('profile-tab'));
If Catalog contains [Catalog, Product], switching to Profile and back restores that exact Catalog stack. Use resetBranch only when you intentionally want to clear it, for example after sign-out.
The complete NavigationBar application is built in Tutorials → Modular tabs.