| title | SiteHeader with Breadcrumbs |
|---|---|
| description | Guide for implementing dynamic breadcrumb navigation in the dashboard header. |
The SiteHeader component displays a sidebar toggle and breadcrumb navigation at the top of each dashboard page. Views set their breadcrumbs using the useBreadcrumbs composable.
services/frontend/src/
├─ composables/
� └─ useBreadcrumbs.ts # Shared breadcrumb state management
├─ components/
� ├─ SiteHeader.vue # Header with sidebar trigger + breadcrumbs
� └─ DashboardLayout.vue # Layout wrapper that includes SiteHeader
The useBreadcrumbs composable manages breadcrumb state across all views.
interface BreadcrumbItem {
label: string // Display text
href?: string // Optional link - omit for current page
}| Property | Type | Description |
|---|---|---|
breadcrumbs |
Readonly<Ref<BreadcrumbItem[]>> |
Current breadcrumb items |
setBreadcrumbs |
(items: BreadcrumbItem[]) => void |
Set the breadcrumb trail |
clearBreadcrumbs |
() => void |
Clear all breadcrumbs |
For pages with fixed titles like Dashboard or Settings:
<script setup lang="ts">
import { onMounted } from 'vue'
import { useBreadcrumbs } from '@/composables/useBreadcrumbs'
const { setBreadcrumbs } = useBreadcrumbs()
onMounted(() => {
setBreadcrumbs([{ label: 'Dashboard' }])
})
</script>For pages that load data (team detail, server view), set breadcrumbs twice:
<script setup lang="ts">
import { onMounted, ref } from 'vue'
import { useRoute } from 'vue-router'
import { useBreadcrumbs } from '@/composables/useBreadcrumbs'
import { TeamService } from '@/services/teamService'
const route = useRoute()
const { setBreadcrumbs } = useBreadcrumbs()
const team = ref(null)
onMounted(async () => {
// Initial loading state
setBreadcrumbs([
{ label: 'Teams', href: '/teams' },
{ label: 'Loading...' }
])
// Fetch and update with actual name
team.value = await TeamService.getTeam(route.params.id)
setBreadcrumbs([
{ label: 'Teams', href: '/teams' },
{ label: team.value.name }
])
})
</script>For deeply nested pages, include the full path:
setBreadcrumbs([
{ label: 'MCP Catalog', href: '/admin/mcp-server-catalog' },
{ label: server.name, href: `/admin/mcp-server-catalog/view/${serverId}` },
{ label: 'Edit' }
])The SiteHeader renders in this order:
- SidebarTrigger - Toggle button for collapsing/expanding sidebar
- Separator - Vertical divider
- Breadcrumbs - Navigation trail with responsive visibility
On mobile, intermediate breadcrumb items are hidden, showing only the current page.
Views no longer pass a :title prop to DashboardLayout:
<template>
<DashboardLayout>
<!-- Page content -->
</DashboardLayout>
</template>- UI Design System - Component design patterns
- Frontend Architecture - View and composable guidelines