How to build breadcrumbs in Vue
Breadcrumb navigation helps users understand their location within a hierarchical site structure and provides quick navigation to parent pages. As the creator of CoreUI with over 12 years of Vue.js experience since 2014, I’ve implemented breadcrumb systems in numerous enterprise applications. A Vue breadcrumb component integrates with Vue Router to automatically generate navigation links based on the current route hierarchy. This approach creates dynamic breadcrumbs that update automatically as users navigate through your application.
Build breadcrumbs using Vue Router metadata and computed properties to generate navigation hierarchy.
<template>
<nav class='breadcrumbs' aria-label='Breadcrumb'>
<ol class='breadcrumb-list'>
<li
v-for='(crumb, index) in breadcrumbs'
:key='index'
class='breadcrumb-item'
>
<router-link
v-if='index < breadcrumbs.length - 1'
:to='crumb.path'
class='breadcrumb-link'
>
{{ crumb.label }}
</router-link>
<span v-else class='breadcrumb-current'>
{{ crumb.label }}
</span>
<span v-if='index < breadcrumbs.length - 1' class='breadcrumb-separator'>/</span>
</li>
</ol>
</nav>
</template>
<script setup>
import { computed } from 'vue'
import { useRoute } from 'vue-router'
const route = useRoute()
const breadcrumbs = computed(() => {
const crumbs = []
const paths = route.path.split('/').filter(p => p)
// Add home
crumbs.push({ label: 'Home', path: '/' })
// Build breadcrumb path
let currentPath = ''
paths.forEach((path, index) => {
currentPath += `/${path}`
const matchedRoute = route.matched[index + 1]
crumbs.push({
label: matchedRoute?.meta?.breadcrumb || path,
path: currentPath
})
})
return crumbs
})
</script>
<style scoped>
.breadcrumbs {
padding: 10px 0;
}
.breadcrumb-list {
display: flex;
align-items: center;
list-style: none;
margin: 0;
padding: 0;
flex-wrap: wrap;
}
.breadcrumb-item {
display: flex;
align-items: center;
}
.breadcrumb-link {
color: #007bff;
text-decoration: none;
padding: 4px 8px;
border-radius: 4px;
transition: background 0.2s;
}
.breadcrumb-link:hover {
background: #f0f0f0;
text-decoration: underline;
}
.breadcrumb-current {
color: #666;
padding: 4px 8px;
}
.breadcrumb-separator {
margin: 0 8px;
color: #999;
}
</style>
Configure routes with breadcrumb metadata:
const routes = [
{
path: '/',
component: Home,
meta: { breadcrumb: 'Home' }
},
{
path: '/products',
component: Products,
meta: { breadcrumb: 'Products' },
children: [
{
path: ':id',
component: ProductDetail,
meta: { breadcrumb: 'Product Details' }
}
]
},
{
path: '/dashboard',
component: Dashboard,
meta: { breadcrumb: 'Dashboard' }
}
]
Best Practice Note
Use route meta fields to define custom breadcrumb labels instead of showing raw URL segments. For dynamic breadcrumbs (like product names), fetch data and update the breadcrumb label in the component. Add structured data markup (JSON-LD) for SEO benefits. Use aria-label and aria-current attributes for accessibility. This is how we implement breadcrumbs in CoreUI for Vue—automatic generation from routes with custom labels, dynamic content support, and full accessibility for enterprise admin panels with deep navigation hierarchies.



