createBreadcrumbs
A composable that extends createSingle for breadcrumb navigation with automatic path truncation.
Usage
The createBreadcrumbs composable manages an ordered path of items. When you select an earlier item, everything after it is removed. Use values() to iterate the current trail for rendering.
<script setup lang="ts">
import { computed } from 'vue'
import { createBreadcrumbs } from '@vuetify/v0'
const breadcrumbs = createBreadcrumbs()
const path = [
{ text: 'Home' },
{ text: 'Documents' },
{ text: 'Projects' },
{ text: 'Vuetify' },
{ text: 'Components' },
{ text: 'Breadcrumbs' },
]
breadcrumbs.onboard(path)
const items = computed(() => breadcrumbs.values())
function reset () {
breadcrumbs.clear()
breadcrumbs.onboard(path)
}
</script>
<template>
<div class="space-y-4">
<nav class="flex items-center gap-1.5 text-sm">
<template
v-for="(ticket, i) in items"
:key="ticket.id"
>
<span v-if="i > 0" class="text-on-surface-variant">/</span>
<button
class="text-primary hover:underline cursor-pointer"
@click="breadcrumbs.select(ticket.id)"
>
{{ ticket.text }}
</button>
</template>
</nav>
<div class="flex items-center gap-3 text-xs text-on-surface-variant">
<span>
Depth: {{ breadcrumbs.depth.value }} ·
At root: {{ breadcrumbs.isRoot.value }}
</span>
<button
class="text-primary hover:underline cursor-pointer"
@click="reset"
>
Reset
</button>
</div>
</div>
</template>
Architecture
createBreadcrumbs extends createSingle with path truncation and derived navigation state:
The Breadcrumbs component consumes createBreadcrumbs as its backing model, similar to how Tabs.Root uses createStep.
Reactivity
Breadcrumb state is always reactive. All derived properties update automatically when items are registered, unregistered, or navigated.
| Property/Method | Reactive | Notes |
|---|---|---|
depth | Ref — count of registered items | |
isRoot | Ref — depth <= 1 | |
isEmpty | Ref — depth === 0 | |
selectedId | Computed — current (last) item ID | |
selectedItem | Computed — current item ticket | |
selectedValue | Computed — current item value | |
selectedIndex | Computed — current item position |
Depth tracking Use depth, isRoot, and isEmpty to conditionally render navigation controls like a “Back” button or hide the breadcrumb trail when at the root level.
Examples
File Explorer
A file explorer that uses createBreadcrumbs to track the user’s position in a folder tree. Clicking a folder calls register() to push it onto the trail, while clicking a breadcrumb calls select() to navigate back — automatically truncating everything after the selected crumb.
File breakdown:
| File | Role |
|---|---|
file-explorer.vue | Interactive file browser with breadcrumb navigation and back button |
tree.ts | Typed folder tree data and FolderNode interface |
Key patterns:
FileBreadcrumbTicketInputextendsBreadcrumbTicketInput<FolderNode>soselectedValueis properly typed — no casting neededEach folder node is stored as the ticket’s
value, keeping the breadcrumb trail and folder listing in sync through the registry itselfisRootcontrols whether the back button is visible
Drill into Home > Documents > Projects > v0-app > src to see the trail grow, then click an earlier crumb to truncate back.
Functions
createBreadcrumbsContext
(_options?: BreadcrumbsContextOptions) => ContextTrinity<R>Creates a breadcrumbs context for dependency injection.
Options
enroll
MaybeRefOrGetter<boolean>When true, newly registered items are automatically selected if not disabled. Useful for pre-selecting items in multi-select scenarios.
mandatory
MaybeRefOrGetter<boolean | "force">Controls mandatory selection behavior: - `false` (default): No mandatory selection enforcement - `true`: Prevents deselecting the last selected item (user must always have one selected) - `'force'`: Automatically selects the first non-disabled item on registration
Properties
selectedId
ComputedRef<any>selectedIndex
ComputedRef<number>selectedItem
ComputedRef<E>selectedValue
ComputedRef<E["value"]>Methods
seek
(direction?: "first" | "last", from?: number, predicate?: (ticket) => boolean) => Z | undefinedSeek for a ticket based on direction and optional predicate
on
<K extends Extensible<RegistryEventName>>(event: K, cb: EventHandler<Z, K>) => voidListen for registry events
off
<K extends Extensible<RegistryEventName>>(event: K, cb: EventHandler<Z, K>) => voidStop listening for registry events
emit
<K extends Extensible<RegistryEventName>>(event: K, data: EventPayload<Z, K>) => voidEmit an event with data
batch
<R>(fn: () => R) => RExecute operations in a batch, deferring cache invalidation and event emission until complete