Skip to main content

Breadcrumb

  • Component overview: Breadcrumb navigation that shows the user's current position in the hierarchy and supports quick navigation to parent levels.
  • Interaction: Non-current items are clickable with a gray background on hover; the current item is not clickable.
  • Implementation note: Prefer using items as the data source. Use itemRender for custom node styles — the underlying composite components are not exposed directly.
  • Figma spec

Basic Usage

Result
Loading...
Live Editor
render(
  <Breadcrumb
    items={[
      { title: 'Home', href: '#' },
      { title: 'Category', href: '#' },
      { title: 'Current Page' },
    ]}
  />,
)

Icon Text Style

Figma supports 3 styles: Icon Text (icon + text), Icon (icon only), and Text (text only).

Result
Loading...
Live Editor
render(
  <Breadcrumb
    items={[
      { title: 'Home', href: '#', icon: <IconPlaceholder size={20} /> },
      { title: 'Category', href: '#', icon: <IconPlaceholder size={20} /> },
      { title: 'Current Page', icon: <IconPlaceholder size={20} /> },
    ]}
  />,
)

Icon Style

For icon-only items, use itemRender to customize the rendered content.

Result
Loading...
Live Editor
render(
  <Breadcrumb
    itemRender={({ isCurrent, item }) => {
      const content = <IconPlaceholder size={20} />

      if (isCurrent) {
        return (
          <span
            aria-label={String(item.title)}
            className="inline-flex items-center justify-center"
          >
            {content}
          </span>
        )
      }

      return (
        <a
          href={item.href}
          aria-label={String(item.title)}
          className="inline-flex items-center justify-center"
        >
          {content}
        </a>
      )
    }}
    items={[
      { title: 'Home', href: '#' },
      { title: 'Category', href: '#' },
      { title: 'Current' },
    ]}
  />,
)

With Ellipsis (4+ Levels)

When there are more than 4 levels, items automatically collapse into first two + ... + last two. The ... is interactive (Figma Style=Compressed): hover/click highlights it, and selecting it opens a dropdown listing the collapsed middle items, indented by depth.

Result
Loading...
Live Editor
render(
  <Breadcrumb
    items={[
      { title: 'Home', href: '#' },
      { title: 'Category', href: '#' },
      { title: 'Sub Category', href: '#' },
      { title: 'Deep', href: '#' },
      { title: 'Workspace', href: '#' },
      { title: 'Current Page' },
    ]}
  />,
)

Long Title Truncation

When using the items API with default rendering, title text is limited to a maximum width of 260px (Figma Label maxWidth=260 + textTruncation=ENDING). Text that exceeds this width is truncated with an ellipsis at the end. When title is a string, the native title attribute is set automatically so the full text is available on hover. Composition mode (passing children directly) is not affected — truncation is controlled by the consumer.

Result
Loading...
Live Editor
render(
  <Breadcrumb
    items={[
      {
        title: 'A very long breadcrumb title that definitely exceeds the max width',
        href: '#',
      },
      { title: 'Current Page' },
    ]}
  />,
)

Figma Style Matrix

StyleDescriptionRecommended approach
Icon TextIcon + textitems + icon
IconIcon onlyitems + itemRender
TextText onlyitems

Props

PropTypeDefaultDescription
itemsBreadcrumbItemData[]-Recommended — data-driven breadcrumb rendering
itemRender({ item, index, isCurrent, items }) => ReactNode-Custom node renderer
separatorReactNode-Custom separator
classNamestring-Custom style class

Data Structure

FieldTypeDefaultDescription
keyReact.Key-Unique key — falls back to index if not provided
titleReactNode-Display content for this level
hrefstring-Navigation URL on click
iconReactNode-Leading icon
currentbooleanfalseMarks this item as the current page
separatorReactNode-Custom separator after this item
type'item' | 'ellipsis''item'Data type — ellipsis is used for collapsed placeholder

Advanced Usage

When the default node does not meet requirements, use itemRender to take full control of individual item rendering instead of manipulating the underlying structural components directly.

Result
Loading...
Live Editor
render(
  <Breadcrumb
    itemRender={({ isCurrent, item }) => (
      <span
        className="inline-flex items-center gap-[var(--Spacing_8)] text-[length:var(--Font-Size-Body)] leading-[var(--Line-Height-Body)]"
        style={{ fontWeight: isCurrent ? 600 : 400 }}
      >
        <span className="flex items-center justify-center">{item.icon}</span>
        {item.title}
      </span>
    )}
    items={[
      { title: 'Home', href: '#', icon: <IconPlaceholder size={20} /> },
      { title: 'Projects', href: '#', icon: <IconPlaceholder size={20} /> },
      { title: 'Current', icon: <IconPlaceholder size={20} /> },
    ]}
  />,
)