import type { Post, Media, Tag } from '@/payload-types' interface ArticleSchemaProps { post: Post url: string } export function ArticleSchema({ post, url }: ArticleSchemaProps) { const { title, publishDate, updatedDate, excerpt, tags = [], seo, subtitle } = post // Resolve tag slugs — tags may be populated objects or just IDs const tagSlugs: string[] = (tags ?? []) .map((t) => (typeof t === 'object' && t !== null ? (t as Tag).name ?? '' : '')) .filter(Boolean) const articleSchema: Record = { '@context': 'https://schema.org', '@type': 'Article', headline: seo?.title ?? title, name: seo?.title ?? title, description: seo?.description ?? excerpt ?? subtitle, datePublished: publishDate, dateModified: updatedDate ?? publishDate, url, mainEntityOfPage: { '@type': 'WebPage', '@id': url, }, author: { '@type': 'Person', name: 'Chris Arter', url: 'https://arter.dev', sameAs: [ 'https://github.com/christopherarter', 'https://bsky.app/profile/arter.dev', 'https://www.linkedin.com/in/chrisarter1/', ], }, publisher: { '@type': 'Person', name: 'Chris Arter', url: 'https://arter.dev', image: { '@type': 'ImageObject', url: 'https://arter.dev/images/chris-arter.jpg', }, }, articleSection: tagSlugs.length > 0 ? tagSlugs[0] : 'Technology', keywords: tagSlugs.join(', '), } // Add image if available from SEO const seoImage = seo?.image if (seoImage && typeof seoImage === 'object') { const img = seoImage as Media if (img.url) { articleSchema['image'] = { '@type': 'ImageObject', url: img.url.startsWith('http') ? img.url : `https://arter.dev${img.url}`, alt: img.alt ?? title, } } } return (