Page (Page Header)
The Page component provides the header + content structure that sits inside the Sandbox Layout main area. It’s a compound component — Page.Root establishes the page context, Page.Header (or Page.HeaderV2) standardizes the title, back navigation, and actions, and Page.Content holds the scrollable body.
Page.Header composes a back link, an icon or logo, the page title, a description, and header-right actions into a single standardized header.
Variations
Header with tabs (Page.HeaderV2)
Page.HeaderV2 is the newer header variant that supports a title row plus a tab strip for section navigation. The tabs are router-driven — each value is a route the tab links to, and the active tab is derived from the current URL.
Installation
import { Page } from "@harnessio/ui/components";
<Page.Root> <Page.Header title="Pipelines" backLink={{ linkText: "Back to project", linkProps: { to: "/project" } }} actions={<Button>New pipeline</Button>} /> <Page.Content>{/* page body */}</Page.Content></Page.Root>;Anatomy
Page is a compound component. Wrap the page in Page.Root, put a header (Page.Header or Page.HeaderV2) at the top, and render the body inside Page.Content.
<Page.Root> <Page.Header title="Pipelines" backLink={{ linkText: "Back to project", linkProps: { to: "/project" } }} > {/* optional content rendered below the description */} </Page.Header>
<Page.Content>{/* page body */}</Page.Content></Page.Root>Page.Root— establishes the header + content context inside the Sandbox Layout main area. Passscrollableto make the content region scroll (and the header stick).Page.Header— the standard header:title(rendered as an<h1>when it’s a string), optionaliconName/logoName,description,backLink, and header-rightactions. Anychildrenrender below the description.Page.HeaderV2— the header variant with atitlerow plus a router-driventabsstrip; also takesbreadcrumbs,description,iconName, andactions.Page.Content— the page body region; fills the remaining space, and scrolls whenPage.Rootisscrollable.
In Page.HeaderV2, each entry in tabs links to a route — the active tab is resolved from the current URL, and exact controls exact-path matching (used for the index route).
Best practices
Do
- Use one
Page.Header(or onePage.HeaderV2) per page, at the top ofPage.Root, so the title and back navigation are consistent across screens. - Reach for
Page.HeaderV2when the page has sub-sections that map to routes; usePage.Headerfor a single-view page. - Put page-level actions in the header’s
actionsslot rather than inside the content.
Don’t
- Don’t nest a second header inside
Page.Content— the header belongs directly underPage.Root. - Don’t use the header tabs for in-page state that isn’t reflected in the URL; they’re built for route navigation.
Accessibility
Keyboard
Page.HeaderV2tabs are rendered as router links, so they’re reachable and activatable with standard link keyboard behavior; the active tab follows the URL.
Labeling
- When
titleis a string, bothPage.HeaderandPage.HeaderV2render it as a semantic<h1>, giving each page a top-level heading. If you pass a non-string node, provide the heading semantics yourself. backLinkrenders a real link labeled bylinkText— keep that text descriptive of where it goes.
Focus & states
- In a
scrollablePage.Root, the header becomes sticky (pinned to the top with a solid background) while the content scrolls beneath it.
Properties
Page.Root
Prop | Required | Default | Type |
|---|---|---|---|
| children | true | ReactNode | |
| scrollable | false | false | boolean |
| mainClassName | false | string | |
| contentClassName | false | string |
Page.Header
Prop | Required | Default | Type |
|---|---|---|---|
| title | true | ReactNode | |
| description | false | ReactNode | |
| iconName | false | IconV2 name | |
| iconSize | false | 'lg' | '2xs' | 'xs' | 'sm' | 'md' | 'lg' | 'xl' |
| logoName | false | LogoV2 name | |
| backLink | false | { linkText: string; linkProps: LinkProps } | |
| actions | false | ReactNode | |
| headerActions | false | ReactNode | |
| favoriteProps | false | Omit<FavoriteIconProps, 'className'> | |
| isLoading | false | false | boolean |
| children | false | ReactNode |
Page.HeaderV2
Prop | Required | Default | Type |
|---|---|---|---|
| title | true | string | ReactNode | |
| description | false | string | |
| iconName | false | IconV2 name | |
| breadcrumbs | false | ReactNode | |
| tabs | false | HeaderV2TabItem[] | |
| tabsVariant | false | 'underlined' | 'underlined' | 'ghost' |
| tabsClassName | false | string | |
| contentTabs | false | false | boolean |
| actions | false | ReactNode | |
| children | false | ReactNode | |
| className | false | string |
The tabs array uses the HeaderV2TabItem shape:
interface HeaderV2TabItem { label: string; value: string; icon?: IconV2NamesType; counter?: number; disabled?: boolean; exact?: boolean;}Page.Content
Prop | Required | Default | Type |
|---|---|---|---|
| children | true | ReactNode | |
| className | false | string |