Bottom navigation
Puts a phone's main destinations along the bottom edge.
Preview
Local preview. It doesn't affect real accounts, environments, or run data.
Compare the same example at each size and density. Switching keeps input values and selection state. Size guidance and comparisons
Runs
Current destination: Runs
Usage
- Put a phone app's three to five main destinations along the bottom edge, within thumb reach. Each Item is a link with an icon above a short label, and current marks the page you're on.
- By default it shows at 760px and narrower, where AppShell hides its sidebar, so the same destinations live in the sidebar on wider screens. Set visible="always" for a phone-only app.
- It stays fixed to the bottom of the viewport and pads the safe area under the home indicator. Wherever it shows, toasts rise above it and an AppShell ends where it begins, so their last lines stay visible. Pad other scrolling content by var(--surf-size-bottom-navigation) plus env(safe-area-inset-bottom). Set position="static" to place it in a frame of your own.
- A badge shows a count, capped at 99+, or a dot when you pass true. badgeLabel says what it means to screen readers, such as "3 unread"; a dot needs one.
- Don't put more than five destinations in it, or fewer than three. Use the sidebar or a Sheet menu for the rest.
- Don't put actions in it, such as Create or Share. It holds destinations; put actions in the page or a Toolbar.
- Don't drop the labels and leave icons alone. Keep each label to one short word, since it truncates on narrow screens.
- Don't switch panels on one screen with it. Use Tabs for that.
Size: SizeProvider size="small" resizes the whole composition, including portals. The default size is Default. Size guidance and comparisons
Anatomy
Root(nav, aria-label) → ul → Item: li → a(aria-current) → icon pill(+ badge) + label + spoken badge
Keyboard and accessibility
- Each destination is a native link: Tab moves between them and Enter follows one.
- The nav landmark takes its name from aria-label, and the current destination reads as the current page.
- A badge reads after the label, as its badgeLabel or its count; the icon and the visual badge stay out of the accessibility tree.
Give each control a name that describes its purpose. Connect error messages to their controls, and signal state with more than color. Automated checks don't replace manual keyboard and assistive technology testing.
Example code
Shared components take their styles from design tokens. Each example sets its own composition and accessibility attributes. The calling screen defines callbacks, refs, and product data.
Key API
The table lists the common wrapper's main props. See the package type declarations for the full types.