--- import smartypants from 'smartypants'; type SEOMetadata = { name?: string title: string description: string image?: { src: string, alt: string } canonicalURL?: URL | null locale?: string }; type OpenGraph = Partial & { type?: string }; type Twitter = Partial & { handle?: string card?: 'summary' | 'summary_large_image' }; export type Props = SEOMetadata & { og?: OpenGraph twitter?: Twitter }; const { name, description, image, locale = 'en', canonicalURL = new URL(Astro.url.pathname, Astro.site), og: _og = {}, twitter: _twitter = {}, } = Astro.props; const title = [Astro.props.title, name].filter(Boolean).join(' | '); const og: OpenGraph = { name, title, description, canonicalURL, image, locale, type: 'website', ..._og }; const twitter: Twitter = { name, title, description, canonicalURL, image, locale, card: 'summary_large_image', ..._twitter }; const ensureSlash = (url: string | URL) => `${url.toString().replace(/\/$/, '')}/`; --- <!-- Page Metadata --> <meta name="generator" content={Astro.generator} /> {canonicalURL && <link rel="canonical" href={ensureSlash(canonicalURL)} />} <title>{title} {og.canonicalURL && } { og.image && ( <> ) } {twitter.card && } {twitter.handle && } { twitter.image && ( <> ) }