Version 0.14.3

Header

A secondary header with title, tags, description, metadata, tabs, and actions.

Page Title

A short description of this page. Supports inline links.
Type
website
Status
Passing
Contributors

Usage#

import { Header } from '@backstage/ui';

<Header title="Page Title" />

API reference#

PropTypeDefaultDescription
title
string
-Page heading displayed in the header.
tags
-Items displayed above the title. Each tag renders as a link when href is provided, or as plain text otherwise. Tags are separated by a small circle divider.
description
string
-Markdown string rendered below the title. Only inline links are supported. Bold, italic, and block-level markdown are not rendered.
metadata
-Key-value pairs displayed below the description.
customActions
ReactNode
-Custom elements rendered in the actions area.
tabs
-Navigation items displayed below the title.
activeTabId
stringnull
-ID of the currently active tab. Omit to auto-detect from the current route. Set to null for no active tab.
breadcrumbsdeprecated
-Breadcrumb trail displayed above the title.
className
string
-Additional CSS class name for custom styling.

Examples#

Tags#

Tags are rendered above the title. Each tag with an href renders as a link; tags without href render as plain text. Tags are separated by a small circle divider.

Page Title

<Header
  title="Page Title"
  tags={[
    { label: 'TypeScript' },
    { label: 'Platform', href: '/platform' },
    { label: 'Gold' },
  ]}
/>

Description#

The description accepts a markdown string with support for inline links. Bold, italic, and block-level markdown are not rendered.

Page Title

A short description of this page. Supports inline links.
<Header
  title="Page Title"
  description="A short description. Supports [inline links](https://backstage.io)."
/>

Metadata#

Key-value pairs displayed below the description.

Page Title

Owner
platform-team
Type
website
<Header
  title="Page Title"
  metadata={[
    { label: 'Owner', value: 'platform-team' },
    { label: 'Type', value: 'website' },
  ]}
/>

Metadata with users#

Use HeaderMetadataUsers as the metadata value to display users as avatars. A single user shows the avatar with their name beside it. Multiple users show a row of avatars — hover to reveal each name via tooltip. When a user has an href, the avatar and name become links.

Page Title

Type
website
Contributors
import { Header, HeaderMetadataUsers } from '@backstage/ui';

<Header
  title="Page Title"
  metadata={[
    { label: 'Type', value: 'website' },
    {
      label: 'Owner',
      value: <HeaderMetadataUsers users={[{ name: 'Giles Peyton-Nicoll', src: '...', href: '/users/giles' }]} />,
    },
    {
      label: 'Contributors',
      value: (
        <HeaderMetadataUsers
          users={[
            { name: 'Alice Johnson', src: '...', href: '/users/alice' },
            { name: 'Bob Smith', src: '...', href: '/users/bob' },
            { name: 'Carol Williams', src: '...', href: '/users/carol' },
          ]}
        />
      ),
    },
  ]}
/>
PropTypeDefaultDescription
users
-List of users to display. A single user shows the avatar with their name beside it. Multiple users show a row of avatars with names revealed on hover via tooltip.

Metadata with status#

Use HeaderMetadataStatus as the metadata value to display a status indicator. The dot colour is driven by the color prop which maps to BUI status tokens. Pass an href to make the label a link.

Page Title

Status
Passing
Build
Coverage
Warning
import { Header, HeaderMetadataStatus } from '@backstage/ui';

<Header
  title="Page Title"
  metadata={[
    {
      label: 'Status',
      value: <HeaderMetadataStatus label="Passing" color="success" />,
    },
    {
      label: 'Build',
      value: <HeaderMetadataStatus label="Failed" color="danger" href="/builds/123" />,
    },
    {
      label: 'Coverage',
      value: <HeaderMetadataStatus label="Warning" color="warning" />,
    },
  ]}
/>

Tabs#

Tabs auto-detect the active tab from the current route when activeTabId is omitted. Pass an explicit activeTabId to override, or null for no active tab.

<Header
  title="Page Title"
  tabs={[
    { id: 'overview', label: 'Overview', href: '/overview' },
    { id: 'checks', label: 'Checks', href: '/checks' },
    { id: 'tracks', label: 'Tracks', href: '/tracks' },
  ]}
/>

Custom actions#

Page Title

<Header
  title="Page Title"
  customActions={<Button>Custom action</Button>}
/>

With menu#

Use customActions to add a dropdown menu.

Page Title

<Header
  title="Page Title"
  customActions={
    <MenuTrigger>
      <ButtonIcon variant="tertiary" icon={<RiMore2Line />} />
      <Menu placement="bottom end">
        <MenuItem href="/settings">Settings</MenuItem>
        <MenuItem onAction={() => {}}>Logout</MenuItem>
      </Menu>
    </MenuTrigger>
  }
/>

Theming#

Our theming system is based on a mix between CSS classes, CSS variables and data attributes. If you want to customise this component, you can use one of these class names below.

  • bui-HeaderTop
  • bui-HeaderStickySentinel
  • bui-HeaderContent
  • bui-HeaderBottom
  • bui-HeaderBreadcrumbs
  • bui-HeaderBreadcrumbsSmall
  • bui-HeaderBreadcrumbLink
  • bui-HeaderBreadcrumbLinkSmall
  • bui-HeaderBreadcrumbSeparator
  • bui-HeaderTitleStack
  • bui-HeaderTitle
  • bui-HeaderTitleSmall
  • bui-HeaderTabsWrapper
  • bui-HeaderControls
  • bui-HeaderTags
  • bui-HeaderTag
  • bui-HeaderDescription
  • bui-HeaderMetaRow
  • bui-HeaderMetaItem

Changelog#

Version 0.14.0#

Breaking Changes

  • Header Breaking The Header component's tabs prop now uses HeaderNavTabItem[] instead of HeaderTab[]. Tabs render as a <nav> element with links and optional dropdown menus instead of role="tablist". A new activeTabId prop controls which tab is highlighted. #33527

    Migration Guide:

    - import { Header, type HeaderTab } from '@backstage/ui';
    + import { Header, type HeaderNavTabItem } from '@backstage/ui';
    
      // Tabs no longer support matchStrategy — active state is controlled via activeTabId
    - const tabs: HeaderTab[] = [
    -   { id: 'overview', label: 'Overview', href: '/overview', matchStrategy: 'prefix' },
    + const tabs: HeaderNavTabItem[] = [
    +   { id: 'overview', label: 'Overview', href: '/overview' },
      ];
    
    - <Header title="My Page" tabs={tabs} />
    + <Header title="My Page" tabs={tabs} activeTabId="overview" />
    
  • Header Breaking Tab href values in the Header component are now resolved through the router context instead of being passed raw to the <a> tag. This means relative href values (e.g. sub3, ./sub4, ../catalog) are now resolved against the current route, and absolute href values may be affected by the router's basename configuration. #33783

    Migration Guide:

    Tab navigation should work the same for absolute href values in most setups. If you use relative href values in tabs, verify they resolve as expected. If your app configures a router basename, check that absolute tab href values still navigate correctly.

Changes

  • Header Added automatic active tab detection to the Header component. When activeTabId is omitted, the active tab is now auto-detected from the current route using matchRoutes. Pass an explicit activeTabId to override, or null for no active tab. #33783

  • Header Fixed HeaderNav hover indicator covering tab text when theme uses opaque background colors. Also fixed an incorrect CSS variable reference (--bui-font-family--bui-font-regular). #33696

Version 0.13.0#

Breaking Changes

  • Header Breaking Renamed internal CSS classes to match the Header component name.

    Migration: If you are targeting these classes directly in your styles, update the following:

    • bui-HeaderPagebui-Header
    • bui-HeaderPageContentbui-HeaderContent
    • bui-HeaderPageBreadcrumbsbui-HeaderBreadcrumbs
    • bui-HeaderPageTabsWrapperbui-HeaderTabsWrapper
    • bui-HeaderPageControlsbui-HeaderControls #33354

Changes

  • HeaderPage Migrated all components from useStyles to useDefinition hook. Exported OwnProps types for each component, enabling better type composition for consumers. #33050

  • Header Fixed incorrect bottom spacing caused by Container using padding-bottom for its default bottom spacing. Changed to margin-bottom and prevented it from applying when Container is used as the Header root element. #33354

Version 0.9.0#

Breaking Changes

  • Header Breaking Changed className prop behavior to augment default styles instead of being ignored or overriding them.

    If you were passing custom className values to any of these components that relied on the previous behavior, you may need to adjust your styles to account for the default classes now being applied alongside your custom classes. #31496