The slim strip above a site's own header that links every site of a family, the same links in the same order on each, with the site being shown marked aria-current="true", in the text colour, underlined in the primary colour as Navbar marks the current page. A labelled <nav> of plain links: the server HTML is the whole bar, so a page that never hydrates shows it as is. On a narrow screen the row scrolls inside itself, never the page, and fades at the side that hides more links, so a name cut at the edge reads as more to come. In browsers that support it the fade and the current site's link in view need no script. Once hydrated, the row fades in any browser and brings the current site's link into view when it is out of view. Links render through OuroProvider's linkComponent, so a link to the site's own path stays in its router.
On this site
This site's own pages use FamilyBar too. Open one with X-ray pointing it out: The Nautilus's story · The home page
Install
Once per app, with Tailwind CSS v4 and an @/* path alias (Ouro HX is built on Base UI, so --base base; skip -t in an existing app):
npx shadcn@latest init --base base --preset nova --yes --no-monoreponpx shadcn@latest add ourostack/ouro-ui/ouro-base#v1.3.10Then the component. From v0.8.0 it installs only the helpers it imports and never touches your stylesheet (Installing):
npx shadcn@latest add ourostack/ouro-ui/family-bar#v1.3.10Or, with the @ouro namespace set up:
npx shadcn@latest add @ouro/ouro-base @ouro/family-barIts tests, stories and Playwright spec are optional. They need Vitest 4.1.11 or later, and from v0.8.0 never change a version your app has (Testing):
npx shadcn@latest add ourostack/ouro-ui/family-bar#v1.3.10 ourostack/ouro-ui/family-bar-tests#v1.3.10import { FamilyBar } from "@/components/ouro/family-bar/family-bar";Paths use shadcn's default @/ alias; the CLI rewrites them to yours.
Example
<FamilyBar
label="Sites"
links={[
{ id: "home", label: "Lantern", href: "https://example.com/" },
{ id: "docs", label: "Docs", href: "https://docs.example.com/" },
{ id: "blog", label: "Blog", href: "https://blog.example.com/" },
]}
current="docs"
/>Use instead when
- Use
Navbarinstead for a site's own pages, under the FamilyBar, andFamilyFooterfor the same links at the foot of the page.
Props
Type: FamilyBarProps.
brand- Type:
ReactNode - The family's mark or name, before the links. It stays in place while the links scroll.
className- Type:
string - Layout only: position (
sticky top-0), grid placement. Appearance classes warn in development. current- Type:
string - The
idof the site being shown. Its link getsaria-current="true", the text colour and a primary underline, so the mark is not colour alone. label- Type:
string - Default:
"Sites" - Names the navigation for screen readers. It is not shown.
links(required)- Type:
readonly FamilyLink[] - The family's sites, in order. Give every site the same list in the same order, so the bar reads the same on each.
ref- Type:
Ref<HTMLElement> - Reaches the rendered element.
Don't use
These are not props. Passing one fails the type check with the fix in the error, and in development a console message names the fix.
children: Not rendered. The bar islinksandbrand.currentPath: Not a prop. FamilyBar marks a site by its id, not by a path:<FamilyBar current="docs">.items: Not a prop. FamilyBar takeslinks:<FamilyBar links={[{ id: "docs", label: "Docs", href: "/" }]} />.
className is for layout only
Pass margins, width and grid placement (mt-4, w-full, col-span-2).
Appearance comes from props, not classes. In development, a class that sets appearance logs one warning per component instance, naming the prop to use instead. A class sets appearance when, after its variants (hover:, sm:) and any ! are removed, it starts with bg-, text-, border-, rounded-, shadow-, font-, ring-, from-, via-, to-, fill- or stroke-, or is border, rounded, shadow or ring, or has a dark: variant. Text wrapping, overflow and table layout classes (text-wrap, text-ellipsis, border-collapse) are layout and do not warn.
Alignment classes (text-center) warn too: set alignment on a parent element.
Types
FamilyLink
One site of a family, in a FamilyBar and a FamilyFooter.
interface FamilyLink {
/** Names the site for `current`: "docs". It is not shown. */
id: string;
/** The site's name, the link's text: "Docs". */
label: string;
/** Where the link goes: the site's home page, "https://docs.example.com/". */
href: string;
}