Files
vue-seo-layer/app/utils/sitePath.ts
Jakub Zych ebb0c8084e feat: breadcrumbs component
- <SeoBreadcrumbs> (UI-SPEC L1): the resolve answer's trail as nav > ol
  with server-rendered links and the last item as aria-current text;
  nothing with fewer than two items, with page meta seo.breadcrumbs false
  or with the option seo.breadcrumbs false; props items, label,
  hideCurrent, locale
- one trail per page: the first rendered instance claims it
  (seoClaimBreadcrumbs, kept per path)
- seoSitePath: same-origin CMS URLs become paths, non-http(s) URLs are
  never links; useSeoLabels takes an optional locale
- L1 default styles with CSS-generated separators
2026-11-04 11:59:17 +01:00

27 lines
955 B
TypeScript

// Links to the site's own pages from absolute CMS URLs: a URL on the site
// URL's origin (or on the request origin) becomes its path, so it renders
// as a NuxtLink; another http(s) URL stays as it is, and anything else
// (javascript:, data: …) becomes '' so it is never rendered as a link.
// Pure; names start with `seo` because app/utils is auto-imported.
export function seoSitePath(url: string, ...origins: Array<string | undefined | null>): string {
if (typeof url !== 'string' || url === '') return ''
if (url.startsWith('/') && !url.startsWith('//')) return url
let parsed: URL
try {
parsed = new URL(url)
} catch {
return ''
}
if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') return ''
for (const o of origins) {
if (!o) continue
try {
if (new URL(o).origin === parsed.origin) return `${parsed.pathname}${parsed.search}` || '/'
} catch {
// not a URL
}
}
return url
}