feat: add SEO utility functions smartTruncate and buildBreadcrumbList (Task 1)
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
/**
|
||||
* Truncate text at a word boundary, appending ellipsis if cut.
|
||||
* Guarantees the result never breaks a word in half.
|
||||
*/
|
||||
export function smartTruncate(text: string, maxLen: number): string {
|
||||
if (text.length <= maxLen) return text
|
||||
const truncated = text.slice(0, maxLen)
|
||||
const lastSpace = truncated.lastIndexOf(" ")
|
||||
return lastSpace > 0 ? truncated.slice(0, lastSpace) + "..." : truncated + "..."
|
||||
}
|
||||
|
||||
/** Breadcrumb segment — name and absolute URL */
|
||||
export interface BreadcrumbSegment {
|
||||
name: string
|
||||
url: string
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a Schema.org BreadcrumbList from ordered segments.
|
||||
* Position is 1-based per Schema.org spec.
|
||||
*/
|
||||
export function buildBreadcrumbList(segments: BreadcrumbSegment[]) {
|
||||
return {
|
||||
"@context": "https://schema.org",
|
||||
"@type": "BreadcrumbList",
|
||||
itemListElement: segments.map((seg, i) => ({
|
||||
"@type": "ListItem",
|
||||
position: i + 1,
|
||||
name: seg.name,
|
||||
item: seg.url,
|
||||
})),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user