Breadcrumb
This library is a work-in-progress. We are releasing it early to gather feedback, but it is not ready for production.
The Breadcrumb component is a wayfinding element that helps make users aware of their current location within an application or website.
Examples
Live Preview
Default
Types
CSS Shadow Parts Customization
Breadcrumb can be customized using CSS Shadow Parts: ::part(ag-breadcrumb-item), ::part(ag-breadcrumb-item-link), ::part(ag-breadcrumb-item-current). The following are meant solely to show how to utilize CSS shadow parts to create custom breadcrumb styles. They are NOT meant to represent best practices or good taste in breadcrumb design!
Minimal with Underline
View Vue Code
<template>
<section>
<div class="mbe4">
<div class="mbe2">
<h2>Default</h2>
</div>
<VueBreadcrumb
:items="items"
@breadcrumb-click="handleClick"
/>
</div>
<div class="mbe4">
<div class="mbe2">
<h2>Types</h2>
</div>
<VueBreadcrumb
class="mbe4"
type="slash"
:items="items"
@breadcrumb-click="handleClick"
/>
<VueBreadcrumb
class="mbe4"
type="bullet"
:items="items"
@breadcrumb-click="handleClick"
/>
<VueBreadcrumb
class="mbe4"
type="arrow"
:items="items"
@breadcrumb-click="handleClick"
/>
<VueBreadcrumb
primary
type="arrow"
:items="items"
@breadcrumb-click="handleClick"
/>
</div>
<div class="mbe4">
<div class="mbe2">
<h2>CSS Shadow Parts Customization</h2>
<p style="margin-top: 0.5rem; margin-bottom: 1rem; color: var(--vp-c-text-2);">
Breadcrumb can be customized using CSS Shadow Parts:
<code>::part(ag-breadcrumb-item)</code>,
<code>::part(ag-breadcrumb-item-link)</code>,
<code>::part(ag-breadcrumb-item-current)</code>. The following are meant solely to show how to utilize CSS shadow parts to create custom breadcrumb styles. They are NOT meant to represent best practices or good taste in breadcrumb design!
</p>
</div>
<div style="display: flex; flex-direction: column; gap: 2rem;">
<div>
<h3>Minimal with Underline</h3>
<div class="mbe3"></div>
<VueBreadcrumb
class="custom-minimal-breadcrumb"
:items="items"
/>
</div>
</div>
</div>
</section>
</template>
<script>
import VueBreadcrumb from "agnosticui-core/breadcrumb/vue";
export default {
name: "BreadcrumbExamples",
components: { VueBreadcrumb },
data() {
return {
items: [
{ label: "Home", href: "#" },
{ label: "About", href: "#about" },
{ label: "Services", href: "#services" },
{ label: "Products", href: "#products" },
],
};
},
methods: {
handleClick(event) {
console.log(
`VueBreadcrumb -> handleClick -- label: ${event.item.label}, href: ${event.item.href}`
);
},
},
};
</script>
<style scoped>
/* Minimalist breadcrumb */
.custom-minimal-breadcrumb::part(ag-breadcrumb-item-link) {
color: var(--vp-c-text-1);
font-weight: 500;
text-decoration: none;
padding: 0.25rem 0.75rem;
border-bottom: 2px solid transparent;
transition: border-color 0.2s ease;
}
.custom-minimal-breadcrumb::part(ag-breadcrumb-item-link):hover {
border-bottom-color: var(--vp-c-brand-1);
}
.custom-minimal-breadcrumb::part(ag-breadcrumb-item-current) {
color: var(--vp-c-brand-1);
font-weight: 700;
padding: 0.25rem 0.75rem;
border-bottom: 2px solid var(--vp-c-brand-1);
}
/* Pill-style breadcrumb */
.custom-pill-breadcrumb::part(ag-breadcrumb-item-link) {
color: #333;
font-weight: 600;
text-decoration: none;
padding: 0.5rem 1.25rem;
border-radius: 50px;
background: #e5e7eb;
transition: all 0.2s ease;
}
.custom-pill-breadcrumb::part(ag-breadcrumb-item-link):hover {
background: #d1d5db;
transform: scale(1.05);
}
.custom-pill-breadcrumb::part(ag-breadcrumb-item-current) {
color: white;
font-weight: 700;
padding: 0.5rem 1.25rem;
border-radius: 50px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
box-shadow: 0 4px 8px rgba(102, 126, 234, 0.3);
}
</style>
Live Preview
View Lit / Web Component Code
import { LitElement, html } from 'lit';
import 'agnosticui-core/breadcrumb';
export class BreadcrumbLitExamples extends LitElement {
// Render in light DOM to access global utility classes
createRenderRoot() {
return this;
}
constructor() {
super();
this.items = [
{ label: 'Home', href: '#' },
{ label: 'About', href: '#about' },
{ label: 'Services', href: '#services' },
{ label: 'Products', href: '#products' },
];
}
firstUpdated() {
// Set up event listeners for breadcrumb items
const breadcrumbs = this.querySelectorAll('ag-breadcrumb');
breadcrumbs.forEach((breadcrumb) => {
breadcrumb.items = this.items;
breadcrumb.addEventListener('breadcrumb-click', (event) => {
console.log(
`ag-breadcrumb -> breadcrumb-click -- label: ${event.detail.item.label}, href: ${event.detail.item.href}`
);
});
});
}
render() {
return html`
<section>
<!-- Default -->
<div class="mbe4">
<div class="mbe2">
<h2>Default</h2>
</div>
<ag-breadcrumb></ag-breadcrumb>
</div>
<!-- Types -->
<div class="mbe4">
<div class="mbe2">
<h2>Types</h2>
</div>
<ag-breadcrumb class="mbe4" type="slash"></ag-breadcrumb>
<ag-breadcrumb class="mbe4" type="bullet"></ag-breadcrumb>
<ag-breadcrumb class="mbe4" type="arrow"></ag-breadcrumb>
<ag-breadcrumb primary type="arrow"></ag-breadcrumb>
</div>
<!-- CSS Shadow Parts Customization -->
<div class="mbe4">
<div class="mbe2">
<h2>CSS Shadow Parts Customization</h2>
<p style="margin-top: 0.5rem; margin-bottom: 1rem; color: var(--vp-c-text-2);">
Breadcrumb can be customized using CSS Shadow Parts:
<code>::part(ag-breadcrumb-item)</code>,
<code>::part(ag-breadcrumb-item-link)</code>,
<code>::part(ag-breadcrumb-item-current)</code>. The following are meant solely to show how to utilize CSS shadow parts to create custom breadcrumb styles. They are NOT meant to represent best practices or good taste in breadcrumb design!
</p>
</div>
<div style="display: flex; flex-direction: column; gap: 2rem;">
<div>
<h3>Minimal with Underline</h3>
<div class="mbe3"></div>
<ag-breadcrumb class="custom-minimal-breadcrumb"></ag-breadcrumb>
</div>
</div>
</div>
</section>
`;
}
}
// Register the custom element
customElements.define('breadcrumb-lit-examples', BreadcrumbLitExamples);
Interactive Preview: Click the "Open in StackBlitz" button below to see this example running live in an interactive playground.
View React Code
import { ReactBreadcrumb } from "agnosticui-core/breadcrumb/react";
export default function BreadcrumbReactExamples() {
const items = [
{ label: "Home", href: "#" },
{ label: "About", href: "#about" },
{ label: "Services", href: "#services" },
{ label: "Products", href: "#products" },
];
const handleClick = (event) => {
console.log(
`ReactBreadcrumb -> handleClick -- label: ${event.item.label}, href: ${event.item.href}`
);
};
return (
<section>
{/* Default */}
<div className="mbe4">
<div className="mbe2">
<h2>Default</h2>
</div>
<ReactBreadcrumb items={items} onBreadcrumbClick={handleClick} />
</div>
{/* Types */}
<div className="mbe4">
<div className="mbe2">
<h2>Types</h2>
</div>
<ReactBreadcrumb
className="mbe4"
type="slash"
items={items}
onBreadcrumbClick={handleClick}
/>
<ReactBreadcrumb
className="mbe4"
type="bullet"
items={items}
onBreadcrumbClick={handleClick}
/>
<ReactBreadcrumb
className="mbe4"
type="arrow"
items={items}
onBreadcrumbClick={handleClick}
/>
<ReactBreadcrumb
primary
type="arrow"
items={items}
onBreadcrumbClick={handleClick}
/>
</div>
{/* CSS Shadow Parts Customization */}
<div className="mbe4">
<div className="mbe2">
<h2>CSS Shadow Parts Customization</h2>
<p style={{ marginTop: "0.5rem", marginBottom: "1rem", color: "var(--vp-c-text-2)" }}>
Breadcrumb can be customized using CSS Shadow Parts:
<code>::part(ag-breadcrumb-item)</code>,
<code>::part(ag-breadcrumb-item-link)</code>,
<code>::part(ag-breadcrumb-item-current)</code>. The following are meant solely to show how to utilize CSS shadow parts to create custom breadcrumb styles. They are NOT meant to represent best practices or good taste in breadcrumb design!
</p>
</div>
<div style={{ display: "flex", flexDirection: "column", gap: "2rem" }}>
<div>
<h3>Minimal with Underline</h3>
<div className="mbe3"></div>
<ReactBreadcrumb className="custom-minimal-breadcrumb" items={items} />
</div>
</div>
</div>
</section>
);
}
Usage
TIP
The framework examples below import AgnosticUI as an npm package. Alternatively, you can use the CLI for complete control, AI/LLM visibility, and full code ownership:
npx ag init --framework FRAMEWORK # react, vue, lit, svelte, etc.
npx ag add BreadcrumbThe CLI copies source code directly into your project, giving you full visibility and control. After running npx ag add, you'll receive exact import instructions.
Vue
<template>
<section>
<div class="mbe4">
<div class="mbe2">
<h3>Default</h3>
</div>
<VueBreadcrumb
:items="items"
@breadcrumb-click="handleClick"
/>
</div>
<div class="mbe4">
<div class="mbe2">
<h3>Types</h3>
</div>
<VueBreadcrumb
type="slash"
:items="items"
@breadcrumb-click="handleClick"
/>
<VueBreadcrumb
type="bullet"
:items="items"
@breadcrumb-click="handleClick"
/>
<VueBreadcrumb
type="arrow"
:items="items"
@breadcrumb-click="handleClick"
/>
<VueBreadcrumb
primary
type="arrow"
:items="items"
@breadcrumb-click="handleClick"
/>
</div>
</section>
</template>
<script>
import VueBreadcrumb from "agnosticui-core/breadcrumb/vue";
export default {
name: "BreadcrumbExamples",
components: { VueBreadcrumb },
data() {
return {
items: [
{ label: "Home", href: "#" },
{ label: "About", href: "#about" },
{ label: "Services", href: "#services" },
{ label: "Products", href: "#products" },
],
};
},
methods: {
handleClick(event) {
console.log(
`VueBreadcrumb -> handleClick -- label: ${event.item.label}, href: ${event.item.href}`
);
},
},
};
</script>React
import { ReactBreadcrumb, type BreadcrumbItem } from 'agnosticui-core/breadcrumb/react';
export default function BreadcrumbExamples() {
const items: BreadcrumbItem[] = [
{ label: 'Home', href: '#' },
{ label: 'About', href: '#about' },
{ label: 'Services', href: '#services' },
{ label: 'Products', href: '#products' },
];
const handleClick = (event: CustomEvent) => {
console.log(
`ReactBreadcrumb -> handleClick -- label: ${event.detail.item.label}, href: ${event.detail.item.href}`
);
};
return (
<section>
<div className="mbe4">
<div className="mbe2">
<h3>Default</h3>
</div>
<ReactBreadcrumb
items={items}
onBreadcrumbClick={handleClick}
/>
</div>
<div className="mbe4">
<div className="mbe2">
<h3>Types</h3>
</div>
<ReactBreadcrumb
type="slash"
items={items}
onBreadcrumbClick={handleClick}
/>
<ReactBreadcrumb
type="bullet"
items={items}
onBreadcrumbClick={handleClick}
/>
<ReactBreadcrumb
type="arrow"
items={items}
onBreadcrumbClick={handleClick}
/>
<ReactBreadcrumb
primary
type="arrow"
items={items}
onBreadcrumbClick={handleClick}
/>
</div>
</section>
);
}Lit (Web Components)
import { LitElement, html, css } from 'lit';
import { customElement } from 'lit/decorators.js';
import 'agnosticui-core/breadcrumb';
@customElement('breadcrumb-example')
export class BreadcrumbExample extends LitElement {
private items = [
{ label: 'Home', href: '#' },
{ label: 'About', href: '#about' },
{ label: 'Services', href: '#services' },
{ label: 'Products', href: '#products' },
];
static styles = css`
:host {
display: block;
}
section {
display: flex;
flex-direction: column;
gap: 1rem;
}
`;
firstUpdated() {
// Set up event listeners for breadcrumb items in the shadow DOM
const breadcrumbs = this.shadowRoot?.querySelectorAll('ag-breadcrumb');
breadcrumbs?.forEach((breadcrumb: any) => {
breadcrumb.items = this.items;
breadcrumb.addEventListener('breadcrumb-click', (event: Event) => {
const customEvent = event as CustomEvent;
console.log(
`ag-breadcrumb -> breadcrumb-click -- label: ${customEvent.detail.item.label}, href: ${customEvent.detail.item.href}`
);
});
});
}
render() {
return html`
<section>
<div class="mbe4">
<div class="mbe2">
<h3>Default</h3>
</div>
<ag-breadcrumb></ag-breadcrumb>
</div>
<div class="mbe4">
<div class="mbe2">
<h3>Types</h3>
</div>
<ag-breadcrumb type="slash"></ag-breadcrumb>
<ag-breadcrumb type="bullet"></ag-breadcrumb>
<ag-breadcrumb type="arrow"></ag-breadcrumb>
<ag-breadcrumb primary type="arrow"></ag-breadcrumb>
</div>
</section>
`;
}
}Note: When using breadcrumb components within a custom element's shadow DOM, set up event listeners in the component's lifecycle (e.g., firstUpdated()) rather than using DOMContentLoaded, as document.querySelector() cannot access elements inside shadow DOM. Use this.shadowRoot.querySelector() instead.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
items | BreadcrumbItem[] | [] | Array of breadcrumb items to display |
type | 'default' | 'slash' | 'bullet' | 'arrow' | 'default' | Separator style between breadcrumb items |
primary | boolean | false | Uses primary (blue) color styling for links |
ariaLabel | string | 'Breadcrumb' | Custom aria-label for the navigation landmark |
BreadcrumbItem Interface
interface BreadcrumbItem {
label: string;
href?: string;
current?: boolean;
}Events
| Event | Framework | Detail | Description |
|---|---|---|---|
breadcrumb-click | Vue: @breadcrumb-clickReact: onBreadcrumbClickLit: @breadcrumb-click or .onBreadcrumbClick | { item: BreadcrumbItem, index: number, event: MouseEvent } | Fired when a breadcrumb link is clicked. Provides the clicked item, its index, and the original mouse event. |
Event Patterns
AgnosticUI Breadcrumb supports three event handling patterns:
- addEventListener (Lit/Vanilla JS):
const breadcrumb = document.querySelector("ag-breadcrumb");
breadcrumb.addEventListener("breadcrumb-click", (e) => {
console.log("Breadcrumb clicked:", e.detail.item.label);
console.log("Item index:", e.detail.index);
e.detail.event.preventDefault();
});- Callback props (Lit/Vanilla JS):
const breadcrumb = document.querySelector("ag-breadcrumb");
breadcrumb.onBreadcrumbClick = (e) => {
console.log("Breadcrumb clicked:", e.detail.item.label);
};- Framework event handlers (Vue/React):
<VueBreadcrumb
:items="items"
@breadcrumb-click="handleClick"
/><ReactBreadcrumb
items={items}
onBreadcrumbClick={handleClick}
/>All three patterns work identically thanks to the dual-dispatch system.
Note: The component does NOT prevent default navigation by default. To implement client-side routing, call event.detail.event.preventDefault() in your event handler.
CSS Shadow Parts
The Breadcrumb component exposes the following CSS Shadow Parts for custom styling:
| Part | Description |
|---|---|
ag-breadcrumb-item | Individual breadcrumb list item wrapper |
ag-breadcrumb-item-link | Clickable breadcrumb link element |
ag-breadcrumb-item-current | Current/active breadcrumb item (non-clickable) |
Customization Example
ag-breadcrumb::part(ag-breadcrumb-item-link) {
color: #667eea;
font-weight: 600;
padding: 0.5rem 1rem;
border-radius: 8px;
transition: all 0.3s ease;
}
ag-breadcrumb::part(ag-breadcrumb-item-link):hover {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
}
ag-breadcrumb::part(ag-breadcrumb-item-current) {
color: #764ba2;
font-weight: 700;
padding: 0.5rem 1rem;
}See the CSS Shadow Parts Customization section in the examples above for more styling demonstrations.
Notes
- The last item or any item with
current: trueis automatically styled as the current page (not clickable) - Items without an
hrefare rendered as plain text - The
primaryprop changes link colors to use the primary theme color (typically blue) - All three implementations share the same underlying styles and behavior
- Use CSS Shadow Parts for advanced customization while maintaining component encapsulation