Skip to content

Patterns · Layout

SiteHeader and SiteFooter

The frame of a public page: wordmark, navigation with disclosure panels, actions, and a footer of link columns.

@rookcom/monarch-react/marketingPattern

Header and footer

Usage examples

The example at the top of the page is the only one for this component.

Purpose

SiteHeader and SiteFooter give every public site the same navigation model and landmarks. Import from @rookcom/monarch-react/marketing.

Use when

  • Product sites, launch pages, docs landing pages and other public pages.

Avoid when

  • Signed-in app screens: use the app shell (RookRail, from @rookcom/monarch-react/shell).
  • Dialog-like flows such as sign-in, where navigation would distract.

Design principles

  • Quiet chrome: a translucent canvas bar with a hairline border, muted links that darken on hover; the wordmark and one primary action carry the brand.
  • Group items open a panel of links with descriptions, not an application menu: they are navigation, so they stay links.
  • No artwork ships in the package. brand is a slot for the product wordmark from your brand kit.
  • Footer column titles are real headings and links meet the 24px target size.

API reference

import { SiteFooter, SiteHeader } from '@rookcom/monarch-react/marketing';
ExportKindRenderingRoot class
SiteFootercomponentserver-safe.mn-site-footer
SiteHeadercomponentclient.mn-site-menu-

nav takes SiteLink (label, href, description?, current?, external?) and SiteNavGroup (label, items).

linkAs renders every link with your router (for example Next.js Link); it receives href, className, aria-current, and target/rel for external links.

Group panels use Radix Popover, portalled to the body.

Generated from the TypeScript declarations of packages/react/src/patterns/layout/marketing-site-shell.

Properties

Site footer: brand, link columns with real headings, and a legal row. Every link has at least a 24px target (WCAG 2.5.8). Server-component safe.

PropTypeDescription
brandReactNodeWordmark (link home).
childrenReactNode
classNamestring
columnsSiteFooterColumn[]
descriptionReactNodeOne sentence about the product or company.
headingAsHeadingLevelHeading element for column titles.
idstring
legalReactNodeCopyright and company line.
legalLinksSiteLink[]Policy links beside the legal line.
linkAsLinkComponentRouter link component. Default `a`.
metaReactNodeExtra content on the trailing edge of the bottom row (language switcher, status).
navLabelstringAccessible name of the footer navigation.

SiteHeader

Site header for marketing and public pages: wordmark, primary navigation with disclosure menus, and actions. Under 768px the navigation collapses into a menu button (`aria-expanded`), closed with Escape.

PropTypeDescription
brand requiredReactNodeProduct wordmark, normally a link home: `<a href="/"><img alt="Rook Dossier" …/></a>`. Monarch ships no artwork; use the product's logo from the Rook brand kit.
actionsReactNodeCalls to action on the trailing edge, e.g. "Log in" and one primary Button.
childrenReactNode
classNamestring
idstring
linkAsLinkComponentRouter link component for nav links (e.g. Next.js Link). Default `a`.
menuLabels{ open: string; close: string; }Labels for the mobile menu toggle.
navSiteNavItem[]Top-level links and groups. Groups open a disclosure panel of links.
navLabelstringAccessible name of the navigation landmark.
stickybooleanStick to the top while scrolling. Default true.

Variants

PropValuesDescription
sticky (SiteHeader)'true''false'Stick to the top while scrolling (default true).
headingAs (SiteFooter)'h2''h3''h4'Heading level of the column titles.

States

StateExposed asBehaviour
Current pagearia-current="page"Set current on a link; it renders in the default text colour.
Group openaria-expanded="true"Trigger tinted, chevron rotated, panel shown.
Mobile menu openaria-expanded="true" (toggle)Below 768px the toggle shows a close icon and the panel lists every link.

Interaction behaviour

  • Clicking a group trigger opens its panel; clicking outside, Escape or choosing a link closes it.
  • Below 768px, links and actions move into a disclosure panel under the bar; Escape closes it and returns focus to the toggle.

Keyboard support

KeysAction
TabMoves through wordmark, links, group triggers and actions.
Enter / SpaceOpens a group panel or the mobile menu.
EscapeCloses the open panel and returns focus to its trigger.

Accessibility

Role
banner and contentinfo landmarks, each with a labelled navigation
Accessible name
navLabel (default "Main" in the header, "Footer" in the footer).
  • The mobile toggle names its action ("Open menu" / "Close menu") and has aria-expanded and aria-controls.
  • External links get target and rel attributes and a visually hidden "(opens in a new tab)".
  • Header targets are at least 36px tall, mobile panel links 44px, footer links 32px (WCAG 2.5.8 needs 24px).

Responsive behaviour

  • From 768px: inline navigation and actions. Below: wordmark plus a 44px menu toggle.
  • Footer: brand above the columns until 1024px, beside them after; columns go from two to auto-fit.

Theme support

  • All colours are semantic tokens; the bar is --mn-color-bg-canvas at 86% with a backdrop blur.
  • Works unchanged in light, dark and more-contrast themes and every product accent.

Do and don't

Do

  • Use the product wordmark from the brand kit as brand, linked home, with the product name as alt text.
  • Keep actions to "Log in" (ghost) and one primary.
  • Pass linkAs so navigation uses client-side routing.

Don't

  • Do not put application menus (actions, checkboxes) in nav groups.
  • Do not add banners, crowns, gold or decorative artwork to the bar.
  • Do not list pages that do not exist yet.

Dependencies

KindDepends on
npm packages@radix-ui/react-popoverreact
Monarch componentsNone

Testing coverage

  • Group triggers open a panel of links; current page is marked.
  • Mobile toggle has aria-expanded, closes on Escape and restores focus.
  • Footer column titles are headings; external links announce the new tab.
  • Landmarks are present with no axe violations; renders on the server.
CheckCovered
Axe in jsdomYes
Server renderingYes
Browser suitesVisual baselines and three-browser axe: /__marketing

Tests: packages/react/src/patterns/layout/marketing-site-shell