Navigation Rails provide access to primary destinations on tablet and desktop screens (md+). On mobile, use a Navbar instead. The Rail is hidden below the md breakpoint and expands to show labels between md and lg with a scrim; at lg+ the scrim disappears and the expanded state is unobtrusive.
The demo below uses anchor="parent" so the Rail positions itself inside its container rather than the viewport.
Page content
bind:collapsed boolean default: true
Whether the rail is in its narrow (collapsed) state. Bind to drive it externally.
expandable boolean default: true
Whether to show the hamburger toggle button. Set false to lock the rail collapsed.
anchor "viewport" | "parent" default: "viewport"
viewport: fixed to the screen edge. parent: absolute within the nearest relative ancestor (good for contained demos).
railTop number default: 0
Top offset in px — use when a top AppBar is present, e.g. railTop={64}.
fab Snippet Optional FAB rendered above the nav items.
railFooter Snippet Optional snippet pinned to the bottom of the rail (avatar, settings link, etc.).
rounded boolean default: false
Adds rounded-xl corners to the rail panel.
href string default: "/"
The destination URL. Active state is derived automatically from the current page URL.
label string Text shown below the icon (collapsed) or beside it (expanded).
iconProps IconProps Passed directly to the Icon component. Required. At minimum: { name: "symbol_name" }.
badge number default: 0
Numeric badge on the icon. Pass -1 for a small dot with no number.
selected boolean default: false
Force the active state regardless of current URL (useful for demo or non-route selection).
disabled boolean default: false
Prevents navigation and dims the item.
external boolean default: false
Opens in a new tab with rel="noopener noreferrer".
Mount the Rail at the top of your root layout alongside the page content. The Rail ghost element reserves the same width so content never slides under it.
<script>
let collapsed = $state(true);
</script>
<!-- In your root +layout.svelte -->
<Rail bind:collapsed railTop={0}>
{#snippet fab()}
<FAB iconProps={{ name: 'add' }} label="New" />
{/snippet}
<RailItem label="Home" href="/" iconProps={{ name: 'house' }} />
<RailItem label="Messages" href="/messages" iconProps={{ name: 'mail' }} badge={5} />
<RailItem label="Settings" href="/settings" iconProps={{ name: 'settings' }} />
{#snippet railFooter()}
<Avatar seed="DV" />
{/snippet}
</Rail>
<!-- Offset page content by the collapsed rail width -->
<div class="md:ml-24">
{@render children()}
</div> The Navbar is the mobile companion to the Rail. It renders as a fixed bottom bar and is hidden
at md+.
Resize to a narrow viewport to see it in action — it's already mounted on this page via the
site layout.
ghost boolean default: false
Renders an invisible same-height spacer after the fixed bar so page content is not obscured behind it. Always use this.
fab Snippet Optional FAB rendered anchored above the bar at bottom-right.
href string default: "/"
The destination URL. Active state is auto-derived from the current page.
label string Text label shown below the icon.
iconProps IconProps Required. At minimum: { name: "symbol_name" }.
badge number default: 0
Numeric badge. Pass -1 for a small dot.
selected boolean default: false
Force active state independently of URL.
Place the Navbar in the same root layout as the Rail. The two components are designed to be used together — Rail handles tablet/desktop, Navbar handles mobile.
<!-- In your root +layout.svelte, alongside Rail -->
<Navbar ghost>
{#snippet fab()}
<FAB size="sm" iconProps={{ name: 'add' }} label="New" />
{/snippet}
<NavbarItem label="Home" href="/" iconProps={{ name: 'house' }} />
<NavbarItem label="Messages" href="/messages" iconProps={{ name: 'mail' }} badge={5} />
<NavbarItem label="Profile" href="/profile" iconProps={{ name: 'person' }} />
</Navbar> | Breakpoint | Rail | Rail scrim | Navbar |
|---|---|---|---|
| < md (mobile) | hidden | hidden | visible (fixed bottom) |
| md – lg (tablet) | collapsed (96px) | visible on expand | hidden |
| lg+ (desktop) | collapsed (96px) | hidden | hidden |