TabNav renders anchor-based tabs that navigate to distinct routes—supervisor subsections, analytics areas, settings hubs. Every tab is a real link, so browser history, middle-click "open in new tab", and URL sharing work the way operators expect from the web platform. The mental model is "these tabs are actually links styled as a tab row"—separate from TabMenu (buttons, no URL change) and separate from Tabs (linked panels on one route).
- Sections operators bookmark or share ("Analytics → Incidents", "Settings → Integrations").
- Top-level groups within a feature where each tab maps to a route segment.
- Any strip where middle-click should open a new browser tab.
- Local filters that should not dirty browser history—use
TabMenu.
- Same-page show/hide panels—use
Tabs with TabsContent.
- Eight or more destinations—sidebars or hierarchical navigation scale better.
- Concise labels in the same vocabulary as the sidebar. Counts use the
counter prop. Localize with formatMessage.
- Parallel grammar across tabs so the row reads as peers.
- Active state. Active tab reflects nested routes. Use
extraRouteMatchers when one tab represents multiple URL patterns; otherwise the wrong tab reads as active on nested pages.
- Sliding indicator. With
slidingAnimation, the underline remeasures its position and width when responsive navigation replaces a visible tab, including destinations promoted from an overflow menu.
- SPA transitions. Avoid full-page flash on navigation. Use framework-native transitions so tab clicks feel instantaneous.
- Hover. Inactive tabs use alt text color and transition to base on hover with
--animation-duration-quick.
- Focus. Tab moves focus onto the link; Enter activates.
Do
- Keep tab counts modest at narrow widths; surface overflow with a menu or an expandable control that still exposes destinations.
- Match density and animation to paired
TabMenu strips in the same area for visual consistency—semantics differ (anchors vs. buttons), but the treatment should feel coherent.
- Keep the active tab in sync with the router on programmatic navigation.
Don't
- Use
TabNav for actions. Navigation only. A link that triggers an operation is a misuse of the pattern.
- Duplicate the same destination from multiple tabs. History becomes ambiguous and Cmd/Ctrl-click produces duplicate windows.
- Hide overflow without exposing the destinations. An overflow that disappears is an IA failure.
Links must have discernible names; the current page is indicated via aria-current or equivalent per the implementation. See Accessibility for the full contract.
- Tab menu for non-navigating filters.
- Tabs for panel toggles on a single route.
- Breadcrumb for deeper hierarchy above tabs.