SEO.astro
1 --- 2 import data from "~/data/sites"; 3 4 export type Props = { 5 title: string; 6 isPost?: boolean; 7 description?: string; 8 keywords?: string[]; 9 thumbnail?: string; 10 publishedAt?: string; 11 }; 12 13 const defaultThumbnail = 14 "https://avatars3.githubusercontent.com/u/51877647?s=240&v=4"; 15 16 function getThumbnailUrl(thumbnail: string | undefined): string { 17 if (!thumbnail) return defaultThumbnail; 18 return thumbnail.toString(); 19 } 20 21 function getTwitterCardType(thumbnail: string | undefined): string { 22 return thumbnail ? "summary_large_image" : "summary"; 23 } 24 25 const { 26 isPost = false, 27 thumbnail, 28 description = data.description, 29 keywords = data.keywords, 30 publishedAt, 31 ...props 32 } = Astro.props as Props; 33 const { siteName, siteUrl, author, twitter } = data; 34 const currentUrl = `${siteUrl}${Astro.url.pathname}`; 35 const thumbnailUrl = getThumbnailUrl(thumbnail); 36 const twitterCard = getTwitterCardType(thumbnail); 37 --- 38 39 <title>{props.title} | {siteName}</title> 40 <meta charset="UTF-8"> 41 <meta name="viewport" content="width=device-width,initial-scale=1.0" /> 42 <meta name="theme-color" content="#fff1f2" /> 43 <link rel="canonical" href={currentUrl} /> 44 <meta name="author" content={author} /> 45 <meta name="description" content={description} /> 46 <meta name="keywords" content={keywords.join(",").toLowerCase()} /> 47 48 <!-- favicon --> 49 <link rel="icon" type="image/png" href="/favicon.png" /> 50 51 <!-- Open Graph / Facebook --> 52 <meta property="og:type" content={isPost ? "article" : "website"} /> 53 <meta property="og:url" content={currentUrl} /> 54 <meta property="og:title" content={props.title || siteName} /> 55 <meta property="og:description" content={description} /> 56 <meta property="og:image" content={thumbnailUrl} /> 57 <meta property="og:site_name" content={siteName} /> 58 <meta property="og:locale" content="en_GB" /> 59 60 {isPost && ( 61 <> 62 <meta property="article:author" content={author} /> 63 <meta property="article:published_time" content={publishedAt} /> 64 <meta property="article:tag" content={keywords.join(",")} /> 65 </> 66 )} 67 68 <!-- Twitter --> 69 <meta property="twitter:site" content={"@" + twitter.split("/").pop()} /> 70 <meta property="twitter:creator" content={"@" + twitter.split("/").pop()} /> 71 <meta property="twitter:card" content={twitterCard} /> 72 <meta property="twitter:url" content={currentUrl} /> 73 <meta property="twitter:title" content={props.title || siteName} /> 74 <meta property="twitter:description" content={description} /> 75 <meta property="twitter:image" content={thumbnailUrl} /> 76 <meta property="twitter:image:alt" content={props.title || siteName} />