Breadcrumbs
Import
Section titled “Import”import { Breadcrumbs } from '@delightstack/components';import type { BreadcrumbItem } from '@delightstack/components';Basic Usage
Section titled “Basic Usage”View code
<script> import { Breadcrumbs } from '@delightstack/components'; import type { BreadcrumbItem } from '@delightstack/components';
const items: BreadcrumbItem[] = [ { label: 'Products', href: '/products' }, { label: 'Electronics', href: '/products/electronics' }, { label: 'Headphones' }, ];</script>
<Breadcrumbs {items} />Examples
Section titled “Examples”Auto-Collapse to Fit
Section titled “Auto-Collapse to Fit”With no max_items set, the trail auto-collapses to fit its container — the first
item and the last two stay pinned while the middle items fold into the “…” menu,
starting from the center. This is done in pure CSS with container queries, so
it’s already correct in server-rendered HTML (no layout flash, no JS measuring).
Drag the right edge ↔ to resize. Items fold into the “…” menu to fit.
View code
<!-- Just render the items — collapsing is automatic --><Breadcrumbs {items} />Collapsed Middle Items (explicit)
Section titled “Collapsed Middle Items (explicit)”Pass max_items to force the whole middle block into the dropdown at a fixed count.
View code
<script> import { Breadcrumbs } from '@delightstack/components';
const items = [ { label: 'Category', href: '/cat' }, { label: 'Subcategory', href: '/cat/sub' }, { label: 'Brand', href: '/cat/sub/brand' }, { label: 'Model', href: '/cat/sub/brand/model' }, { label: 'Product' }, ];</script>
<Breadcrumbs {items} max_items={3} />Tightens the spacing between items and separators for compact layouts like toolbars.
View code
<Breadcrumbs {items} dense />Without Home Icon
Section titled “Without Home Icon”Hide the automatic home breadcrumb.
View code
<Breadcrumbs {items} show_home={false} />Custom Separator
Section titled “Custom Separator”Replace the default chevron separator with a custom snippet.
View code
<Breadcrumbs {items}> {#snippet separator()} <span>/</span> {/snippet}</Breadcrumbs>View code
<Breadcrumbs {items} size="0" /> <!-- Small --><Breadcrumbs {items} size="1" /> <!-- Default --><Breadcrumbs {items} size="2" /> <!-- Medium --><Breadcrumbs {items} size="3" /> <!-- Large -->Click Handler
Section titled “Click Handler”React to breadcrumb clicks without relying solely on native navigation. The
onclick handler fires for crumbs that have no href (crumbs with an href
navigate natively).
Promise-aware loading. If your onclick handler returns a promise, the
clicked crumb automatically shows a loading spinner until the promise settles,
then clears it — the trail re-flows smoothly as the spinner appears and
disappears. This is ideal for async work like validating a step or fetching
data before the view updates, with no extra loading state to manage yourself.
View code
<script> import { Breadcrumbs } from '@delightstack/components';
const items = [ { label: 'Home' }, { label: 'Products' }, { label: 'Detail' }, ];
let status = $state('');
// Returning a promise drives the per-crumb loading spinner. function navigate({ item, index }) { status = `Loading "${item.label}"…`; return new Promise((resolve) => { setTimeout(() => { status = `Clicked "${item.label}" (index ${index})`; resolve(); }, 1200); }); }</script>
<Breadcrumbs {items} show_home={false} onclick={navigate} />Skeleton Loading
Section titled “Skeleton Loading”The skeleton mirrors the real trail’s box exactly (size and spacing), so swapping
between loading and loaded states never shifts the layout. It scales with size,
shows the home icon when show_home is set, and is automatically replaced the
moment real items are provided.
View code
<!-- skeleton shows only while items is empty --><Breadcrumbs skeleton skeleton_count={3} items={loading ? [] : items} />| Prop | Type | Default | Description |
|---|---|---|---|
items | BreadcrumbItem[] | [] | The breadcrumb items to display |
max_items | number | undefined | Max visible items before collapsing the middle block into the ellipsis dropdown. When omitted, the trail auto-collapses to fit its container width (pure CSS, SSR-safe) |
show_home | boolean | true | Whether to show a home icon as the first breadcrumb |
home_href | string | '/' | The href for the home breadcrumb |
size | '0' | '1' | '2' | '3' | '1' | Size of the breadcrumbs |
dense | boolean | false | Condensed spacing between items and separators |
skeleton | boolean | false | Show skeleton loading state (only while items is empty) |
skeleton_count | number | 3 | Number of skeleton placeholder items |
id | string | auto | Element ID |
class | string | '' | Additional CSS classes |
children | Snippet | undefined | Custom rendering snippet (replaces default rendering) |
separator | Snippet | undefined | Custom separator snippet |
Events
Section titled “Events”| Event | Detail | Description |
|---|---|---|
onclick | { item: BreadcrumbItem, index: number } | Fires when a breadcrumb item without an href is clicked. May return a promise — while it’s pending, the clicked crumb shows a loading spinner |
BreadcrumbItem
Section titled “BreadcrumbItem”interface BreadcrumbItem { label: string; href?: string;}Auto-collapse
Section titled “Auto-collapse”When max_items is omitted, the component estimates each item’s width from its
label length and uses CSS container query units
to decide what fits. Because the decision is made entirely in CSS, the correct
collapsed state is present in the first server-rendered paint — there’s no
measure-then-reflow flash. The first item and the last two are always kept; the
middle items fold into the “…” menu from the center outward as space shrinks.
Estimates are intentionally approximate (proportional fonts vary), so leave a
little breathing room if precise control matters — or set max_items explicitly.
Accessibility
Section titled “Accessibility”- Uses
<nav>witharia-label="Breadcrumb" - Semantic
<ol>list for the breadcrumb trail - Last item has
aria-current="page" - Home icon includes screen-reader-only text (
<span class="sr-only">) - The ellipsis uses a native
<details>/<summary>disclosure (keyboard- and screen-reader-friendly, works without JS) - Collapsed (zero-width) copies are marked
inertwhen JS is available, so only the visible copy is focusable and announced - Automatically generates Schema.org
BreadcrumbListJSON-LD for SEO