Skip to main content

Navigation

FamilyFooter

The foot of a family's site: the FamilyBar's links, in the same order, in a quiet row that wraps, with the site being shown marked the same way, and the site's own extras (children) after them. The family's links are a labelled <nav> of plain links, whole in the server HTML.

On this site

This site's own pages use FamilyFooter 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-monorepo
npx shadcn@latest add ourostack/ouro-ui/ouro-base#v1.3.10

Then 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-footer#v1.3.10

Or, with the @ouro namespace set up:

npx shadcn@latest add @ouro/ouro-base @ouro/family-footer

Its 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-footer#v1.3.10 ourostack/ouro-ui/family-footer-tests#v1.3.10
import { FamilyFooter } from "@/components/ouro/family-bar/family-footer";

Paths use shadcn's default @/ alias; the CLI rewrites them to yours.

Example

<FamilyFooter links={sites} current="docs">
  <Link href="/privacy" tone="secondary">Privacy</Link>
  <Link href="/terms" tone="secondary">Terms</Link>
</FamilyFooter>

Use instead when

  • Use FamilyBar instead for the strip above the site's header, and Navbar for a site's own pages.

Props

Type: FamilyFooterProps.

children
Type: ReactNode
The site's own extras, after the family's links: its Privacy and Terms links, a line about who makes it. They fill the rest of the row, or a row of their own, and sit at its end (at its start on a phone) until you spread them: me-auto on the first.
className
Type: string
Layout only: margins, grid placement (mt-auto). Appearance classes warn in development.
current
Type: string
The id of the site being shown, marked as in the FamilyBar: aria-current="true", the text colour and a primary underline.
label
Type: string
Default: "All sites"
Names the footer's navigation for screen readers, apart from the bar's. It is not shown.
links (required)
Type: readonly FamilyLink[]
The family's sites, in order: the list the site's FamilyBar takes.
ref
Type: Ref<HTMLDivElement>
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.

  • currentPath: Not a prop. FamilyFooter marks a site by its id, not by a path: <FamilyFooter current="docs">.
  • items: Not a prop. FamilyFooter takes links: <FamilyFooter 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

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;
}