Skip to main content
Urbicon UI

Breadcrumb

Navigation aid showing the current page's location in a hierarchy.

Playground

Size
Max Items
<script lang="ts">
  import { Breadcrumb } from '@urbicon-ui/blocks';

  const items = [
    { label: 'Home', href: '#' },
    { label: 'Store', href: '#' },
    { label: 'Audio', href: '#' },
    { label: 'Headphones', href: '#' },
    { label: 'AirPods Max' }
  ];
</script>

<Breadcrumb
  {items}
/>

01 Examples

From the current path

Breadcrumbs usually mirror the route, so derive them from the path instead of hand-listing each crumb. Wrapping the call in $derived(itemsFromPath(page.url.pathname)) (with page from $app/state) re-runs it on every navigation, so the trail follows the current route. The last segment is the current page.
<script lang="ts">
  import { page } from '$app/state';
  import { Breadcrumb, type BreadcrumbItem } from '@urbicon-ui/blocks';

  // Each segment becomes a crumb; its href is the path up to it.
  function itemsFromPath(pathname: string): BreadcrumbItem[] {
    const segments = pathname.split('/').filter(Boolean);
    return segments.map((segment, i) => ({
      label: segment.replace(/-/g, ' ').replace(/^[a-z]/, (c) => c.toUpperCase()),
      href: '/' + segments.slice(0, i + 1).join('/')
    }));
  }

  // Re-runs on every navigation, so the trail follows the current route.
  const items = $derived(itemsFromPath(page.url.pathname));
</script>

<Breadcrumb {items} />

Icons

A per-item icon renders before that crumb's label. Pass the icon component itself (icon: HomeIcon), never its name, because a name pulls the whole icon set into the bundle. The same trail also swaps the default / for a ChevronRightIcon through the separator snippet, which sets the separator for every crumb.
<script lang="ts">
  import { Breadcrumb, HomeIcon, ChevronRightIcon } from '@urbicon-ui/blocks';
</script>

<Breadcrumb
  items={[
    { label: 'Home', href: '/', icon: HomeIcon },
    { label: 'Blog', href: '/blog' },
    { label: 'Architecture', href: '/blog/architecture' },
    { label: 'Monorepo Setup' }
  ]}
>
  {#snippet separator()}
    <ChevronRightIcon size={14} />
  {/snippet}
</Breadcrumb>

Collapsing long paths

Set maxItems to fold the middle of a deep trail into an expandable ellipsis (…). itemsBeforeCollapse and itemsAfterCollapse keep that many items at each end, and the current page is always shown. Clicking the ellipsis reveals the full path and moves focus to the first revealed item.
<Breadcrumb items={veryDeepItems} maxItems={4} itemsBeforeCollapse={2} size="sm" />

02 Customization

Pill links

Restyle the trail into pill links with slotClasses and semantic tokens only. Each ancestor link sits in a neutral surface pill that shifts to a primary tint on hover, and the current page is a solid primary pill that marks position. The pill radius comes from the commit tier, so it tracks the theme rather than hardcoding rounded-full.
<Breadcrumb
  items={galleryItems}
  slotClasses={{
    link: 'rounded-commit border border-border-subtle bg-surface-interactive px-2.5 py-1 text-text-secondary hover:bg-surface-selected hover:text-primary hover:no-underline focus-visible:rounded-commit',
    currentPage: 'rounded-commit bg-primary px-2.5 py-1 text-text-on-primary',
    separator: 'mx-1'
  }}
>
  {#snippet separator()}
    <ChevronRightIcon size={14} />
  {/snippet}
</Breadcrumb>

This is one of five ways to restyle a block. See Customization for class, slotClasses, unstyled, preset and provider-level overrides.

03 Accessibility

Built-in ARIA

Renders as a <nav> with aria-label="Breadcrumb", overridable with the aria-label prop. The last item carries aria-current="page" to announce the current page. A per-item icon is decorative: it renders inside an aria-hidden wrapper, so the crumb announces as its label alone. Give an icon-only crumb its own aria-label when the label is too terse to stand on its own.

Keyboard

All breadcrumb links are standard <a> elements, fully focusable via Tab. Focus indicators use focus-visible: to only show on keyboard navigation.

Semantic Markup

Uses an ordered list (<ol>) inside the <nav> landmark, following the WAI-ARIA Breadcrumb pattern. Separators are marked aria-hidden="true" to avoid screen reader clutter.

Reduced Motion

Hover transitions on links respect prefers-reduced-motion via the design-token-based transition duration.

04 API Reference

15 props
15 props 1 required
Prop
Type
Default
Description

05 Types

Local type definitions used by this component.

6 types
Name
Kind
Category
Used by
Description

06 Installation

Import

import { Breadcrumb } from '@urbicon-ui/blocks';