type MediaLike = { url?: string | null } | null | undefined type ArticleJsonLdArgs = { /** Article headline (the title). */ headline: string /** Absolute URL of the article. */ url: string description?: string /** Cover/hero image. */ image?: MediaLike /** ISO date the article was first published, e.g. '2026-01-15'. */ datePublished?: string /** ISO date of the last modification. Defaults to datePublished. */ dateModified?: string /** Author name (person or org). */ author?: string /** Publisher (usually the site/organization) name. */ publisherName?: string /** Publisher logo (for the Article rich result). */ publisherLogo?: MediaLike /** 'Article' (default), 'BlogPosting', or 'NewsArticle'. */ type?: 'Article' | 'BlogPosting' | 'NewsArticle' } /** * Builds Article / BlogPosting JSON-LD (schema.org) for blog posts and articles. * Enables article rich results in Google (headline, date, author, image). Pairs * with the plugin's content collections (blog/archives). * * Per-article (each post emits its own), data from the document + panel: * * import { buildArticleJsonLd } from '@intecion/ipal-kit' * const jsonLd = buildArticleJsonLd({ * headline: post.title, url: postUrl, description: post.excerpt, * image: post.coverImage, datePublished: post.publishedAt, * author: post.author, publisherName: settings.siteName, * publisherLogo: settings.logo, type: 'BlogPosting', * }) * * All data from the document/panel — nothing hardcoded. Google requires headline * and dates for the rich result; supply them from the post's real fields. */ export function buildArticleJsonLd({ headline, url, description, image, datePublished, dateModified, author, publisherName, publisherLogo, type = 'Article', }: ArticleJsonLdArgs) { const imageUrl = image?.url const logoUrl = publisherLogo?.url const abs = (u: string | null | undefined): string | undefined => u ? (u.startsWith('http') ? u : `${url.split('/').slice(0, 3).join('/')}${u}`) : undefined return { '@context': 'https://schema.org', '@type': type, headline, url, mainEntityOfPage: { '@type': 'WebPage', '@id': url }, ...(description ? { description } : {}), ...(imageUrl ? { image: abs(imageUrl) } : {}), ...(datePublished ? { datePublished } : {}), ...(dateModified || datePublished ? { dateModified: dateModified ?? datePublished } : {}), ...(author ? { author: { '@type': 'Person', name: author } } : {}), ...(publisherName ? { publisher: { '@type': 'Organization', name: publisherName, ...(logoUrl ? { logo: { '@type': 'ImageObject', url: abs(logoUrl) } } : {}), }, } : {}), } }