Navigation
Navigate between pages with push, pop, and replace
Fuse provides a Navigator component that manages a page stack, backed by Flutter's Navigator 2.0.
Basic setup
import { Navigator } from "solid-fuse";
function App() {
return <Navigator initialPage={() => <HomePage />} />;
}initialPage accepts either a JSX thunk (sugar for a default Material page) or a PageConfig built with materialPage({...}) when you want to customize the transition or page options.
useNavigation
Any component inside a Navigator can access the navigation API:
import { GestureDetector, Text, View, useNavigation } from "solid-fuse";
function HomePage() {
const nav = useNavigation();
return (
<View flex={{ gap: 16 }} padding={24}>
<Text fontSize={24}>Home</Text>
<GestureDetector onTap={() => nav.push(() => <DetailPage />)}>
<View padding={12} decoration={{ color: "blue", borderRadius: 8 }}>
<Text color="white">Go to detail</Text>
</View>
</GestureDetector>
</View>
);
}API
| Method | Description |
|---|---|
nav.push(page) | Push a page. page is a JSX thunk or a PageConfig. Returns a promise that resolves with the value passed to pop(result), or null if the page is removed any other way (back gesture, replaceAll, disposal). |
nav.pop(result?) | Pop the top page. Optional result resolves the pending push promise. No-op on a single-entry stack. |
nav.pushReplacement(page, result?) | Replace the top page. Pending promise of the replaced page resolves with result. |
nav.popUntil(name?) | Pop until the named route is on top, or to the root if no name given. No-op (with warning) if the name isn't on the stack. |
nav.replaceAll(configs) | Replace the entire stack with new pages. Returns a promise per new page. |
nav.stackDepth() | Reactive getter for the current stack depth. |
nav.pages() | Reactive getter for the page entry list. |
Pages are configs, not JSX
A page in Fuse is a configuration object — { type, child, props } — not a JSX element you render directly. The built-in materialPage({...}) factory returns one of these configs for a Material-style transition.
import { Text, View, materialPage, useNavigation } from "solid-fuse";
function HomePage() {
const nav = useNavigation();
const openSettings = () =>
nav.push(
materialPage({
name: "settings",
fullscreenDialog: true,
child: () => <SettingsPage />,
}),
);
return (
<View padding={24}>
<Text>...</Text>
</View>
);
}When you pass a plain thunk to nav.push(() => <X />), it's sugar for materialPage({ child: () => <X /> }).
materialPage props
| Prop | Type | Default | Description |
|---|---|---|---|
child | () => JSX.Element | required | Page contents (thunk so it isn't built until the page is mounted) |
name | string | — | Route name. Used by popUntil(name) |
fullscreenDialog | boolean | false | Slides up instead of sideways, shows close button |
maintainState | boolean | true | Keep state alive when not the top page |
Back gestures
iOS swipe-back and Android back button are handled automatically. The Navigator's onDidRemovePage callback fires when the system removes a page (back gesture, declarative mid-stack removal) and resolves the corresponding push promise with null. You don't need to wire this up.
Full example
A two-page app with a list and detail view:
import { createSignal, For } from "solid-js";
import {
GestureDetector,
Navigator,
Text,
View,
useNavigation,
} from "solid-fuse";
const items = ["Apples", "Bananas", "Cherries"];
function App() {
return <Navigator initialPage={() => <ListPage />} />;
}
function ListPage() {
const nav = useNavigation();
return (
<View flex={{ gap: 4 }}>
<Text fontSize={24} fontWeight="bold" padding={{ bottom: 8 }}>
Fruits
</Text>
<For each={items}>
{(item) => (
<GestureDetector onTap={() => nav.push(() => <DetailPage name={item} />)}>
<View
padding={16}
decoration={{ border: { bottom: { width: 1, color: "#E0E0E0" } } }}
>
<Text fontSize={16}>{item}</Text>
</View>
</GestureDetector>
)}
</For>
</View>
);
}
function DetailPage(props: { name: string }) {
const nav = useNavigation();
return (
<View flex={{ align: "center", justify: "center", expand: true }}>
<Text fontSize={32}>{props.name}</Text>
<GestureDetector onTap={() => nav.pop()}>
<Text color="blue" fontSize={16}>Back to list</Text>
</GestureDetector>
</View>
);
}Returning a value from a page
nav.push returns a promise that resolves to whatever pop(result) is called with — or null if the page is removed any other way:
const selected = await nav.push<string>(() => <PickerPage />);
if (selected !== null) {
// user picked something
}Inside the picker:
function PickerPage() {
const nav = useNavigation();
return (
<GestureDetector onTap={() => nav.pop("apple")}>
<Text>Pick apple</Text>
</GestureDetector>
);
}Custom page types
You can build custom page types with different transitions. See Creating Pages for how to build your own Material, Cupertino, or fade-transition factories.