Rocky_Mountain_Vending/components/breadcrumbs.tsx

105 lines
2.6 KiB
TypeScript

import Link from "next/link"
import { ChevronRight, Home } from "lucide-react"
import { businessConfig } from "@/lib/seo-config"
export interface BreadcrumbItem {
label: string
href?: string | null
}
interface BreadcrumbsProps {
items: BreadcrumbItem[]
className?: string
}
/**
* Breadcrumb Navigation Component
* Implements BreadcrumbList schema markup for SEO and navigation clarity
* Helps search engines understand page hierarchy
*/
export function Breadcrumbs({ items, className = "" }: BreadcrumbsProps) {
// Build breadcrumb list for schema
const schemaItems = items.reduce<
Array<{
"@type": "ListItem"
position: number
name: string
item?: string
}>
>((acc, item, index) => {
const isLast = index === items.length - 1
if (!item.href && !isLast) {
return acc
}
acc.push({
"@type": "ListItem",
position: acc.length + 2,
name: item.label,
...(item.href
? {
item: item.href.startsWith("http")
? item.href
: `${businessConfig.website}${item.href}`,
}
: {}),
})
return acc
}, [])
const breadcrumbList = {
"@context": "https://schema.org",
"@type": "BreadcrumbList",
itemListElement: [
{
"@type": "ListItem",
position: 1,
name: "Home",
item: businessConfig.website,
},
...schemaItems,
],
}
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(breadcrumbList) }}
/>
<nav
className={`flex items-center gap-2 text-sm text-muted-foreground ${className}`}
aria-label="Breadcrumb"
>
<Link
href="/"
className="hover:text-foreground transition-colors flex items-center gap-1"
aria-label="Home"
>
<Home className="h-4 w-4" />
</Link>
{items.map((item, index) => (
<div key={index} className="flex items-center gap-2">
<ChevronRight className="h-4 w-4" />
{index === items.length - 1 ? (
<span className="text-foreground font-medium" aria-current="page">
{item.label}
</span>
) : !item.href ? (
<span className="text-foreground font-medium">{item.label}</span>
) : (
<Link
href={item.href}
className="hover:text-foreground transition-colors"
>
{item.label}
</Link>
)}
</div>
))}
</nav>
</>
)
}