101 lines
2.8 KiB
Plaintext
101 lines
2.8 KiB
Plaintext
---
|
|
export interface OgImage {
|
|
url: string;
|
|
width: number;
|
|
height: number;
|
|
alt: string;
|
|
type?: string;
|
|
}
|
|
|
|
interface Props {
|
|
title: string;
|
|
description: string;
|
|
canonicalPath?: string;
|
|
canonicalOverride?: string;
|
|
ogType?: 'website' | 'article';
|
|
ogImage?: OgImage;
|
|
noindex?: boolean;
|
|
publishedTime?: Date;
|
|
modifiedTime?: Date;
|
|
articleTags?: string[];
|
|
jsonLd?: Record<string, unknown> | Record<string, unknown>[];
|
|
}
|
|
|
|
const {
|
|
title,
|
|
description,
|
|
canonicalPath,
|
|
canonicalOverride,
|
|
ogType = 'website',
|
|
ogImage,
|
|
noindex = false,
|
|
publishedTime,
|
|
modifiedTime,
|
|
articleTags = [],
|
|
jsonLd,
|
|
} = Astro.props;
|
|
|
|
const SITE_NAME = 'Unique';
|
|
const titleTag = title === SITE_NAME ? SITE_NAME : `${title} — ${SITE_NAME}`;
|
|
|
|
const canonicalUrl =
|
|
canonicalOverride ??
|
|
new URL(canonicalPath ?? Astro.url.pathname, Astro.site).href;
|
|
|
|
const jsonLdBlocks = jsonLd
|
|
? Array.isArray(jsonLd)
|
|
? jsonLd
|
|
: [jsonLd]
|
|
: [];
|
|
---
|
|
|
|
<meta charset="UTF-8" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
<title>{titleTag}</title>
|
|
<meta name="description" content={description} />
|
|
<link rel="canonical" href={canonicalUrl} />
|
|
{noindex && <meta name="robots" content="noindex,nofollow" />}
|
|
|
|
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
|
|
<meta name="theme-color" content="#fafaf7" />
|
|
<link rel="alternate" type="application/rss+xml" title={`${SITE_NAME} — RSS`} href="/rss.xml" />
|
|
|
|
<meta property="og:type" content={ogType} />
|
|
<meta property="og:title" content={title} />
|
|
<meta property="og:description" content={description} />
|
|
<meta property="og:url" content={canonicalUrl} />
|
|
<meta property="og:site_name" content={SITE_NAME} />
|
|
<meta property="og:locale" content="en_US" />
|
|
{ogImage && (
|
|
<>
|
|
<meta property="og:image" content={ogImage.url} />
|
|
<meta property="og:image:width" content={String(ogImage.width)} />
|
|
<meta property="og:image:height" content={String(ogImage.height)} />
|
|
<meta property="og:image:alt" content={ogImage.alt} />
|
|
{ogImage.type && <meta property="og:image:type" content={ogImage.type} />}
|
|
</>
|
|
)}
|
|
|
|
{ogType === 'article' && publishedTime && (
|
|
<meta property="article:published_time" content={publishedTime.toISOString()} />
|
|
)}
|
|
{ogType === 'article' && modifiedTime && (
|
|
<meta property="article:modified_time" content={modifiedTime.toISOString()} />
|
|
)}
|
|
{ogType === 'article' &&
|
|
articleTags.map((t) => <meta property="article:tag" content={t} />)}
|
|
|
|
<meta name="twitter:card" content="summary_large_image" />
|
|
<meta name="twitter:title" content={title} />
|
|
<meta name="twitter:description" content={description} />
|
|
{ogImage && (
|
|
<>
|
|
<meta name="twitter:image" content={ogImage.url} />
|
|
<meta name="twitter:image:alt" content={ogImage.alt} />
|
|
</>
|
|
)}
|
|
|
|
{jsonLdBlocks.map((block) => (
|
|
<script type="application/ld+json" is:inline set:html={JSON.stringify(block)} />
|
|
))}
|