Skip to content
LogoLogo

Breadcrumbs

Breadcrumbs help users navigate through the application and provide visual wayfinding.

Loading...

Overview

Resources

Install

yarn add @camp/breadcrumbs

Props

PropTypeDefaultDescription
crumbs *CrumbType[]Array of crumbs to display in the breadcrumb.
currentPage *stringTitle displayed when not editing. The title of the current page that the user is on.
inputProps *Pick<InputHTMLAttributes<HTMLInputElement>, "disabled" | "value" | "autoFocus" | "onBlur" | "onChange" | "onKeyDown" | "placeholder"> & Required<...>Subset of HTML input props. `aria-label` is required to keep the input accessible.
isEditing *booleanControlled by parent — whether edit mode is active.
onCancel *() => voidCalled when the Cancel button is clicked.
onEditStart *() => voidCalled when the edit icon button is clicked.
onSave *() => voidCalled when the Save button is clicked.
type"editable" | "fixed"Determines the variant. Defaults to 'fixed'.

Generated from @camp/breadcrumbs@6.15.0 source, ordered by production usage. * required. † standard HTML attribute — all native attributes are supported; only those with production usage are listed.

Upgrading to Next Gen

🎨 Updated color palette and style refresh: Aligned styling with our refreshed brand standards, delivering a modernized and cohesive look and feel.

🏷️ New tag property within the crumbs object: Be explicit in choosing whether the Breadcrumbs component should render a link or button under the hood.

Previous implementation

import { Breadcrumbs, BreadcrumbLink } from '@activecampaign/camp-components-breadcrumbs';
 
const crumbs: BreadcrumbLink[] = [
    { href: 'https://www.activecampaign.com/', text: 'First Crumb' }, // the component will determine whether to render a link or button by the presence of the `href` or `onClick` props
    {
      onClick: (e:React.MouseEvent<HTMLButtonElement>) => console.log(`/path/to/second/crumb`),
      text: 'Second Crumb',
    },
  ]
 
   ...
   return (
      <Breadcrumbs crumbs={crumbs} currentPage="Current Page" />
   )

New implementation

The new Breadcrumbs API very much resembles its predecessor, but there is a key difference to be aware of:

In the previous implementation, the component would determine whether to render a link or button based on the presence of the href or onClick props. In the new implementation, you must explicitly tell the component to render a link or button by setting the tag property to either 'a' or 'button'.

import { Breadcrumbs, CrumbProps } from "@camp/breadcrumbs";
 
const crumbs: CrumbsType[] = [
   { tag: 'a', children: 'First Crumb', href: 'google.com' }, // by telling the component to render an anchor tag, Typescript will enable intellisense / autocomplete for HTMLAnchorElement props
   ...
   { tag: 'button', children: 'Fifth Crumb', onClick: () => console.log('clicked') }, // by telling the component to render a button tag, Typescript will enable intellisense / autocomplete for HTMLButtonElement props
   ...
]
 
   ...
   return (
      <Breadcrumbs crumbs={crumbs} currentPage="Current Page" />
   )

Migration steps

  1. Update import path: Replace the old tabs imports from @camp/breadcrumbs per the section above titled "New Implementation".
  2. Update type name: When setting up a list of crumbs, pull in the CrumbProps type from the @camp/breadcrumbs package, instead of the old BreadcrumbLink type.
  3. Specify the tag prop for each crumb: This is required, and will determine whether the component renders an anchor tag or button under the hood.

Usage

Default

Loading...

import { Breadcrumbs, CrumbProps } from '@camp/breadcrumbs';
 
const crumbs: CrumbsType[] = [
  { tag: 'a', children: 'First Crumb', href: 'google.com' },
  { tag: 'button', children: 'Second Crumb' },
];
...
return <Breadcrumbs crumbs={crumbs} currentPage="Current Page" />;

Overflow

Typically, Breadcrumbs should be no longer than three levels when including the current page. When a flow is particularly complex, overflow can be applied to save space.

In development, the internal logic of Breadcrumbs automatically handles placing the middle crumbs into an overflow menu if the array of crumbs exceeds a length of 2.

Use 'overflow' sparingly as it can add complexity to a page if it isn't required for wayfinding purposes.


Loading...

import { Breadcrumbs, CrumbProps } from '@camp/breadcrumbs';
 
const crumbs: CrumbsType[] = [
  { tag: 'a', children: 'First Crumb', href: 'google.com' },
  { tag: 'a', children: 'Second Crumb', href: 'google.com' },
  { tag: 'a', children: 'Third Crumb', href: 'google.com' },
  { tag: 'a', children: 'Fourth Crumb', href: 'google.com' },
]; // more than 2 crumbs will automatically trigger overflow
 
...
 
return <Breadcrumbs crumbs={crumbs} currentPage="Current Page" />;

Production Examples

More states from @camp/breadcrumbs's visual test stories, ranked by production usage. Variations already documented above are not repeated here.

import { Breadcrumbs } from '@camp/breadcrumbs';
 
const crumbs: CrumbType[] = [
  { as: 'a', children: 'First Crumb', href: 'https://www.activecampaign.com/' },
  {
    as: 'a',
    children: 'Second Crumb',
    href: 'https://www.activecampaign.com/',
  },
  { as: 'a', children: 'Third Crumb', href: 'https://www.activecampaign.com/' },
  { as: 'a', children: 'Fourth Crumb', href: 'https://www.activecampaign.com/' },
  { as: 'button', children: 'Fifth Crumb', onClick: () => console.log('clicked') },
  { as: 'button', children: 'Sixth Crumb', onClick: () => console.log('clicked') },
];
 
<Breadcrumbs currentPage="Current Page" crumbs={crumbs.slice(4, 6)} />
import { Breadcrumbs } from '@camp/breadcrumbs';
 
const crumbs: CrumbType[] = [
  { as: 'a', children: 'First Crumb', href: 'https://www.activecampaign.com/' },
  {
    as: 'a',
    children: 'Second Crumb',
    href: 'https://www.activecampaign.com/',
  },
  { as: 'a', children: 'Third Crumb', href: 'https://www.activecampaign.com/' },
  { as: 'a', children: 'Fourth Crumb', href: 'https://www.activecampaign.com/' },
  { as: 'button', children: 'Fifth Crumb', onClick: () => console.log('clicked') },
  { as: 'button', children: 'Sixth Crumb', onClick: () => console.log('clicked') },
];
 
<Breadcrumbs currentPage="Current Page" crumbs={crumbs.slice(3, 5)} />
import { Breadcrumbs } from '@camp/breadcrumbs';
 
const crumbs: CrumbType[] = [
  { as: 'a', children: 'First Crumb', href: 'https://www.activecampaign.com/' },
  {
    as: 'a',
    children: 'Second Crumb',
    href: 'https://www.activecampaign.com/',
  },
  { as: 'a', children: 'Third Crumb', href: 'https://www.activecampaign.com/' },
  { as: 'a', children: 'Fourth Crumb', href: 'https://www.activecampaign.com/' },
  { as: 'button', children: 'Fifth Crumb', onClick: () => console.log('clicked') },
  { as: 'button', children: 'Sixth Crumb', onClick: () => console.log('clicked') },
];
 
<Breadcrumbs currentPage="Current Page" crumbs={crumbs} />

Accessibility

Keyboard support

  • Move focus to each breadcrumb using the tab key, or shift + tab to move backwards
  • To interact with the breadcrumb link when it has keyboard focus, use the space or enter key
  • When there are three or more crumbs, tab can also be used to focus on the overflow menu icon, with space or enter used to open the overflow menu and or to traverse links
  • When the overflow menu is open, space or enter can also be used to visit a link
Copyright © 2026 ActiveCampaign