45 lines
1.6 KiB
TypeScript
45 lines
1.6 KiB
TypeScript
type Crumb = {
|
||
/** Visible name of the breadcrumb (e.g. 'Usługi'). */
|
||
name: string
|
||
/** Absolute URL of this crumb (e.g. 'https://example.com/pl/uslugi'). */
|
||
url: string
|
||
}
|
||
|
||
/**
|
||
* Builds BreadcrumbList JSON-LD (schema.org) for a page's position in the site
|
||
* hierarchy. Google can show breadcrumbs in the result (Dom › Usługi › Detailing)
|
||
* and uses them to understand structure — a signal that helps navigational
|
||
* results and sitelinks.
|
||
*
|
||
* Unlike Organization/WebSite (site-wide, root layout), breadcrumbs are
|
||
* PER-PAGE — build them from the page's ancestry and emit on that page:
|
||
*
|
||
* import { buildBreadcrumbJsonLd } from '@intecion/ipal-kit'
|
||
* const jsonLd = buildBreadcrumbJsonLd([
|
||
* { name: 'Strona główna', url: `${base}/pl` },
|
||
* { name: 'Usługi', url: `${base}/pl/uslugi` },
|
||
* { name: 'Detailing', url: `${base}/pl/uslugi/detailing` },
|
||
* ])
|
||
* <script type="application/ld+json" ... />
|
||
*
|
||
* The crumb data comes from the page's real position (parent pages / URL path),
|
||
* NOT hardcoded. Derive it from the resolved route, not a static list.
|
||
*
|
||
* Returns null for an empty/single crumb list — a one-item breadcrumb isn't
|
||
* meaningful and shouldn't be emitted.
|
||
*/
|
||
export function buildBreadcrumbJsonLd(crumbs: Crumb[]) {
|
||
if (!crumbs || crumbs.length < 2) {return null}
|
||
|
||
return {
|
||
'@context': 'https://schema.org',
|
||
'@type': 'BreadcrumbList',
|
||
itemListElement: crumbs.map((crumb, index) => ({
|
||
name: crumb.name,
|
||
'@type': 'ListItem',
|
||
item: crumb.url,
|
||
position: index + 1,
|
||
})),
|
||
}
|
||
}
|