Breadcrumbs
@cloudflare/kumo
import { Breadcrumbs } from "@cloudflare/kumo";
import { HouseIcon } from "@phosphor-icons/react";

export function BreadcrumbsWithIconsDemo() {
  return (
    <Breadcrumbs>
      <Breadcrumbs.Link href="#" icon={<HouseIcon size={16} />}>
        Home
      </Breadcrumbs.Link>
      <Breadcrumbs.Separator />
      <Breadcrumbs.Link href="#">Projects</Breadcrumbs.Link>
      <Breadcrumbs.Separator />
      <Breadcrumbs.Current>Current Project</Breadcrumbs.Current>
    </Breadcrumbs>
  );
}

Installation

import { Breadcrumbs } from "@cloudflare/kumo";

Usage

import { Breadcrumbs } from "@cloudflare/kumo";

export function BreadcrumbsDemo() {
  return (
    <Breadcrumbs>
      <Breadcrumbs.Link href="#">Home</Breadcrumbs.Link>
      <Breadcrumbs.Separator />
      <Breadcrumbs.Link href="#">Docs</Breadcrumbs.Link>
      <Breadcrumbs.Separator />
      <Breadcrumbs.Current>Breadcrumbs</Breadcrumbs.Current>
    </Breadcrumbs>
  );
}

Examples

Basic

import { Breadcrumbs } from "@cloudflare/kumo";

export function BreadcrumbsDemo() {
  return (
    <Breadcrumbs>
      <Breadcrumbs.Link href="#">Home</Breadcrumbs.Link>
      <Breadcrumbs.Separator />
      <Breadcrumbs.Link href="#">Docs</Breadcrumbs.Link>
      <Breadcrumbs.Separator />
      <Breadcrumbs.Current>Breadcrumbs</Breadcrumbs.Current>
    </Breadcrumbs>
  );
}

Loading

import { Breadcrumbs } from "@cloudflare/kumo";
import { HouseIcon } from "@phosphor-icons/react";

export function BreadcrumbsLoadingDemo() {
  return (
    <Breadcrumbs>
      <Breadcrumbs.Link href="#" icon={<HouseIcon size={16} />}>
        Home
      </Breadcrumbs.Link>
      <Breadcrumbs.Separator />
      <Breadcrumbs.Link href="#">Docs</Breadcrumbs.Link>
      <Breadcrumbs.Separator />
      <Breadcrumbs.Current loading></Breadcrumbs.Current>
    </Breadcrumbs>
  );
}

Root

import { Breadcrumbs } from "@cloudflare/kumo";
import { HouseIcon } from "@phosphor-icons/react";

export function BreadcrumbsRootDemo() {
  return (
    <Breadcrumbs>
      <Breadcrumbs.Current icon={<HouseIcon size={16} />}>
        Worker Analytics
      </Breadcrumbs.Current>
    </Breadcrumbs>
  );
}

Clipboard

import { Breadcrumbs } from "@cloudflare/kumo";

export function BreadcrumbsWithClipboardDemo() {
  return (
    <Breadcrumbs>
      <Breadcrumbs.Link href="#">Home</Breadcrumbs.Link>
      <Breadcrumbs.Separator />
      <Breadcrumbs.Current>Breadcrumbs</Breadcrumbs.Current>
      <Breadcrumbs.Clipboard text="#" />
    </Breadcrumbs>
  );
}

Overflow (Prototype)

When breadcrumbs overflow their container, items collapse into a dropdown menu. Drag the slider to resize and watch items collapse.

600px
import { useState } from "react";
import { Breadcrumbs, BreadcrumbItem } from "@cloudflare/kumo";
import { HouseIcon, DatabaseIcon } from "@phosphor-icons/react";

/**
 * Interactive demo showing the items-based API with automatic overflow.
 * Drag the slider to resize and watch items collapse into a dropdown.
 *
 * This demo showcases:
 * - Automatic overflow with tree visualization in dropdown
 * - Icons on breadcrumb items
 * - Custom render prop for router integration (simulated)
 * - Loading state toggle
 */
export function BreadcrumbsOverflowDemo() {
  const [width, setWidth] = useState(600);
  const [isLoading, setIsLoading] = useState(false);

  // Simulated router Link component
  const RouterLink = ({
    to,
    children,
    ...props
  }: {
    to: string;
    children?: React.ReactNode;
    className?: string;
  }) => (
    <a href={to} {...props}>
      {children}
    </a>
  );

  const items: BreadcrumbItem[] = [
    {
      label: "Acme Corp",
      icon: <HouseIcon size={16} className="shrink-0" />,
      // Using render prop for custom link component (e.g., Next.js Link)
      render: <RouterLink to="#" />,
    },
    { label: "Workers & Pages", href: "#" },
    { label: "production-db", href: "#" },
  ];

  const currentItem: BreadcrumbItem = {
    label: "Settings",
    icon: <DatabaseIcon size={16} className="shrink-0" />,
    loading: isLoading,
  };

  return (
    <div className="flex w-full flex-col gap-4">
      <div className="flex flex-wrap items-center gap-3">
        <label className="text-sm text-kumo-subtle whitespace-nowrap">
          Container width:
        </label>
        <input
          type="range"
          min={200}
          max={700}
          value={width}
          onChange={(e) => setWidth(Number(e.target.value))}
          className="flex-1 max-w-48"
        />
        <span className="text-sm text-kumo-subtle tabular-nums w-14">
          {width}px
        </span>
        <label className="flex items-center gap-2 text-sm text-kumo-subtle">
          <input
            type="checkbox"
            checked={isLoading}
            onChange={(e) => setIsLoading(e.target.checked)}
          />
          Loading
        </label>
      </div>

      <div
        className="border border-kumo-line rounded-lg p-5 bg-kumo-base"
        style={{ width }}
      >
        <Breadcrumbs
          items={items}
          currentItem={currentItem}
          collapseFrom="start"
          minVisibleItems={1}
        />
      </div>
    </div>
  );
}

API Reference

PropTypeDefaultDescription
size"sm" | "base""base"Size of the breadcrumbs. - `"sm"` — Compact breadcrumbs for dense UIs - `"base"` — Default breadcrumbs size
childrenReactNode--
classNamestring-Additional CSS classes merged via `cn()`.
PropTypeDefault
href*string-
iconReact.ReactNode-
PropTypeDefault
loadingboolean-
iconReact.ReactNode-
PropTypeDefault

No component-specific props. Accepts standard HTML attributes.

PropTypeDefault
text*string-