NavigationStack
NavigationStack presents a root page and retained destination pages with push and pop transitions.
Push local page factories
Section titled “Push local page factories”[[huxerui::composable]]View HomePage() { auto navigation = UseNavigation(); return Button("Open details").OnClick([navigation] { navigation.Push(DetailsPage, 42); });}
View App() { return NavigationStack(HomePage);}Variadic Push and Replace bind copyable page arguments without a forwarding lambda.
Model addressable routes
Section titled “Model addressable routes”For serializable or externally addressable destinations, use a typed NavigationPath<Route>:
enum class Route { Details, Settings };
View App() { auto path = UseState(NavigationPath<Route>{}); return NavigationStack(HomePage, path, [](Route route) -> View { switch (route) { case Route::Details: return DetailsPage(); case Route::Settings: return SettingsPage(); } return Text("Unknown route"); });}Route values carry stable destination identity and parameters, not retained View objects.
Resolve nested and root navigation
Section titled “Resolve nested and root navigation”NavigationController offers Push, Pop, Replace, CanPop, and Depth. RouteNavigationController<Route> adds SetPath and performs typed route mutations. UseRootNavigation() resolves the outermost compatible stack, which is useful from nested navigation. Route values must be copyable and equality-comparable.
Retain page state and motion
Section titled “Retain page state and motion”The stack retains covered pages and their local state. NavigationStyle provides inherited motion; a PageTransition on the page root defines push/pop/replace effects and timing.
Pages keep the semantics declared by their child views rather than deriving labels from route values. Use labelled controls for push and pop actions, and keep route identity separate from user-facing labels.
NavigationStack(root_factory)and argument-binding overload.NavigationStack(root_factory, State<NavigationPath<Route>>, resolver).UseNavigation()/UseRootNavigation()for factory stacks.UseNavigation<Route>()/UseRootNavigation<Route>()for routed stacks.NavigationPath<Route>:Empty,Size,Routes, equality.NavigationController:Push,Pop,Replace,CanPop,Depth.RouteNavigationController<Route>:Push,Pop,Replace,SetPath,CanPop,Depth.
See Navigation and routing for browser URL integration.
Controller operations and route identity
Section titled “Controller operations and route identity”| Operation | Factory stack | Typed route stack |
|---|---|---|
Push |
Retains a page factory and copied bound arguments. | Appends one Route value to the controlled path. |
Pop() -> bool |
Removes the current destination when possible. | Removes the last route; false at the fixed root. |
Replace |
Replaces the current page factory. | Replaces the last route; throws at the fixed root. |
SetPath |
Not available. | Replaces the route sequence; an empty path returns to the fixed root. |
CanPop / Depth |
Queries the connected stack. | Depth includes the root, so an empty path has depth one. |
Route equality is destination identity for reconciliation. Put stable identifiers and parameters in the Route, not an open file grant, controller, or mutable View. Changing parameters that participate in equality can change retained page identity. NavigationPath::Routes() returns a read-only span: copy the path’s values before replacing the owning State rather than retaining a span across mutation.
UseNavigation chooses the nearest compatible stack; UseRootNavigation chooses the outermost compatible one. Typed and factory controllers are distinct, and a typed lookup must find the matching Route type. A missing compatible stack is a logic error. After disconnect, controller queries return zero/false, Pop returns false, and Push/Replace require a live stack.
Transition fields and page work
Section titled “Transition fields and page work”NavigationStyle::motion is an optional PageTransition. Each push/pop/replace field is a TransitionSpec. A PageTransition attached to the page root overrides the complete inherited policy; it is not a partial field merge. PageTransition makes all three operations immediate. Push and replace use the incoming page; pop uses the departing page. See navigation motion for a complete declaration.
SharedElement and SharedBounds marks inside participating pages follow that operation automatically. They preserve visual continuity without creating another navigation stack or global registry. Use distinct stable keys and prepare assets before the operation. Page content does not accept interaction during motion; Back and predictive cancellation are handled by the container.
Covered page retention preserves local State; it does not imply that every external producer or task pauses. Tie expensive work to application-visible destination policy when it must stop offscreen. Browser history integration uses BrowserNavigationStack, not serialization of factory captures.

