Skip to content
Nizivo UI

PageHeader

The top of a page, under the shell's top bar. The page's one <h1>, an optional status beside it and a line under it, and the page's controls at the row's end. Server-rendered, no client JS.

Server component, no client JS

Import

import { PageHeader } from '@nizivo/react/page-header';

// Once per app (Getting started), after
// @nizivo/tokens/tokens.css and @nizivo/react/css/base.css
import '@nizivo/react/css/page-header.css';

Static or interactive

Server. PageHeader renders a <header> with no client JavaScript. What you put in actions keeps its own tier: a Button stays server-rendered, a SegmentedControl hydrates. How to choose.

In a client app (a Vite or React Router single-page app, or a 'use client' file) it is an ordinary React component: event handlers, refs and state work as usual. In a client app.

One heading per page

title renders the page's <h1>. The shell's top bar shows the section name as text, not as a second heading. Inside a page whose <h1> is elsewhere, pass level={2}; the title keeps its look.

Layout

Figma draws the title (Heading/H1) and the controls on one row, 16 px apart and centred, the controls at the row's end. meta sits beside the title, for example a status <Badge>; description is a Body/M line under it. Below the sm breakpoint (40rem) the title takes Heading/H2's size, as 08's mobile frame does, and the controls move to a row of their own. Hooks: --nz-page-header-gap, --nz-page-header-title-font.

Examples

Basic

The Overview's header (08): the greeting, the range and Export. The header is a server component; the SegmentedControl is its one client part.

Good morning, Maya

import type { JSX } from 'react';
import { Button } from '@nizivo/react/button';
import { SegmentedControl } from '@nizivo/react/segmented-control';
import { PageHeader } from '@nizivo/react/page-header';

/** A stand-in for `@nizivo/icons`' download. */
function Download(): JSX.Element {
  return (
    <svg viewBox="0 0 24 24" width="1em" height="1em" fill="none" stroke="currentColor">
      <path d="M12 15V3M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5" />
    </svg>
  );
}

const RANGES = [
  ['today', 'Today'],
  ['7d', '7D'],
  ['30d', '30D'],
  ['90d', '90D'],
  ['12m', '12M'],
] as const;

export function PageHeaderExample(): JSX.Element {
  return (
    <PageHeader
      title="Good morning, Maya"
      actions={
        <>
          <SegmentedControl.Root aria-label="Range" name="range" defaultValue="30d">
            {RANGES.map(([value, label]) => (
              <SegmentedControl.Item key={value} value={value}>
                {label}
              </SegmentedControl.Item>
            ))}
          </SegmentedControl.Root>
          <Button leadingIcon={<Download />}>Export</Button>
        </>
      }
    />
  );
}

Detail

A resource page (08 Pattern 2): a status Badge after the title, a line under it, two actions.

Stoneware mug

Active

Last edited today at 09:12

import type { JSX } from 'react';
import { Badge } from '@nizivo/react/badge';
import { Button } from '@nizivo/react/button';
import { PageHeader } from '@nizivo/react/page-header';

export function PageHeaderDetailExample(): JSX.Element {
  return (
    <PageHeader
      title="Stoneware mug"
      meta={<Badge tone="success">Active</Badge>}
      description="Last edited today at 09:12"
      actions={
        <>
          <Button>Preview</Button>
          <Button variant="primary">Save</Button>
        </>
      }
    />
  );
}

Props

Server component Renders data-slot="page-header" with the class nz-page-header. Props: PageHeaderProps. Source: src/page-header/page-header.tsx.

NameTypeDefaultDescription
actionsReactNode–

The page's controls at the row's end, for example a SegmentedControl and Buttons.

descriptionReactNode–

A line under the title, Body/M in text/secondary.

levelPageHeaderTitleLevel
12
1

2 for a page whose <h1> is elsewhere. Its look stays Heading/H1.

metaReactNode–

Beside the title, for example a status <Badge>.

renderRenderProp<Record<string, never>>–
titlerequiredReactNode–

The page's title. One <h1> per page: the shell's top bar does not repeat it as a heading.

  • Also takes every attribute of <header> except children, title. (Omit<ComponentPropsWithRef<"header">, "title" | "children">)

render takes an element, or, in client code, a function of the props and no state.

Other exports

PageHeaderProps type

import type { PageHeaderProps } from '@nizivo/react/page-header'

The props of PageHeader, listed above.

PageHeaderTitleLevel type

import type { PageHeaderTitleLevel } from '@nizivo/react/page-header'

type PageHeaderTitleLevel = 1 | 2

Data attributes and slots

Style parts by class (.nz-<slot>) and state by data attribute. Attribute meanings come from contracts/vocabulary.json.

SlotRendered byData attributes
page-header
.nz-page-header
PageHeader
root (takes render)
none
page-header-actions
.nz-page-header-actions
PageHeader
inner element (CSS only)
none
page-header-content
.nz-page-header-content
PageHeader
inner element (CSS only)
none
page-header-description
.nz-page-header-description
PageHeader
inner element (CSS only)
none
page-header-heading
.nz-page-header-heading
PageHeader
inner element (CSS only)
none
page-header-meta
.nz-page-header-meta
PageHeader
inner element (CSS only)
none
page-header-title
.nz-page-header-title
PageHeader
inner element (CSS only)
none

CSS hooks

Set a hook on the component's class or any ancestor to restyle it without specificity games; leave it unset for the default shown.

HookDefaultRead as
--nz-page-header-gap--nz-space-4
  • gap on .nz-page-header
--nz-page-header-title-font
  • default: var(--nz-font-heading-h2)
  • default @media (min-width: 40rem): var(--nz-font-heading-h1)
  • font on .nz-page-header-title

Layers: nz.components. Classes: .nz-page-header, .nz-page-header-actions, .nz-page-header-content, .nz-page-header-description, .nz-page-header-heading, .nz-page-header-meta, .nz-page-header-title.

Tokens this stylesheet reads (12)

--nz-font-body-m, --nz-font-heading-h1, --nz-font-heading-h2, --nz-space-1, --nz-space-2, --nz-space-3, --nz-space-4, --nz-text-primary, --nz-text-secondary, --nz-tracking-body-m, --nz-tracking-heading-h1, --nz-tracking-heading-h2

Accessibility

Nothing in this component takes focus or keyboard input.

Keyboard

KeysAction
TabReaches the controls in the actions slot, in order. The header and its title take no focus.

Source: Native elements only; no engine. Checked by the browser lane (test/browser/table.spec.tsx) in Chromium, Firefox and WebKit.

Figma

Node ids from design/component-map.json, which nz gen writes from component.json. The links open the Nizivo Figma library, which may ask you to sign in.

  • Canonical: none
  • Ghost masters: none

On this page