Spaces:
Running
Running
--- | |
interface Props { | |
title: string; | |
description?: string; | |
authors?: string[]; | |
published?: string; | |
tags?: string[]; | |
image?: string; // Preferred absolute URL | |
} | |
const { title, description = '', authors = [], published, tags = [], image } = Astro.props as Props; | |
const url = Astro.url?.toString?.() ?? ''; | |
const site = (Astro.site ? String(Astro.site) : '') as string; | |
const ogImage = image && image.length > 0 | |
? (image.startsWith('http') ? image : (site ? new URL(image, site).toString() : image)) | |
: undefined; | |
const jsonLd = { | |
'@context': 'https://schema.org', | |
'@type': 'Article', | |
headline: title, | |
description: description || undefined, | |
datePublished: published || undefined, | |
author: authors.map((name) => ({ '@type': 'Person', name })), | |
keywords: tags.length ? tags.join(', ') : undefined, | |
mainEntityOfPage: url || undefined, | |
image: ogImage ? [ogImage] : undefined, | |
}; | |
--- | |
<title>{title}</title> | |
<meta name="description" content={description} /> | |
<link rel="canonical" href={url} /> | |
<meta property="og:type" content="article" /> | |
<meta property="og:title" content={title} /> | |
{description && <meta property="og:description" content={description} />} | |
<meta property="og:url" content={url} /> | |
{ogImage && <meta property="og:image" content={ogImage} />} | |
{published && <meta property="article:published_time" content={published} />} | |
{authors.map(a => <meta property="article:author" content={a} />)} | |
<meta name="twitter:card" content={ogImage ? 'summary_large_image' : 'summary'} /> | |
<meta name="twitter:title" content={title} /> | |
{description && <meta name="twitter:description" content={description} />} | |
{ogImage && <meta name="twitter:image" content={ogImage} />} | |
<script type="application/ld+json" set:html={JSON.stringify(jsonLd)} /> | |