101 lines
3.5 KiB
JavaScript
101 lines
3.5 KiB
JavaScript
import Head from 'next/head'
|
|
import { useRouter } from 'next/router'
|
|
import siteMetadata from '@/data/siteMetadata'
|
|
|
|
export const PageSeo = ({ title, description }) => {
|
|
const router = useRouter()
|
|
return (
|
|
<Head>
|
|
<title>{`${title}`}</title>
|
|
<meta name="robots" content="follow, index" />
|
|
<meta name="description" content={description} />
|
|
<meta property="og:url" content={`${siteMetadata.siteUrl}${router.asPath}`} />
|
|
<meta property="og:type" content="website" />
|
|
<meta property="og:site_name" content={siteMetadata.title} />
|
|
<meta property="og:description" content={description} />
|
|
<meta property="og:title" content={title} />
|
|
<meta property="og:image" content={`${siteMetadata.siteUrl}${siteMetadata.socialBanner}`} />
|
|
<meta name="twitter:card" content="summary_large_image" />
|
|
<meta name="twitter:site" content={siteMetadata.twitter} />
|
|
<meta name="twitter:title" content={title} />
|
|
<meta name="twitter:description" content={description} />
|
|
<meta name="twitter:image" content={`${siteMetadata.siteUrl}${siteMetadata.socialBanner}`} />
|
|
</Head>
|
|
)
|
|
}
|
|
|
|
export const BlogSeo = ({ title, summary, date, lastmod, url, images = [] }) => {
|
|
const router = useRouter()
|
|
const publishedAt = new Date(date).toISOString()
|
|
const modifiedAt = new Date(lastmod || date).toISOString()
|
|
let imagesArr =
|
|
images.length === 0
|
|
? [siteMetadata.socialBanner]
|
|
: typeof images === 'string'
|
|
? [images]
|
|
: images
|
|
|
|
const featuredImages = imagesArr.map((img) => {
|
|
return {
|
|
url: `${siteMetadata.siteUrl}${img}`,
|
|
alt: title,
|
|
}
|
|
})
|
|
|
|
const structuredData = {
|
|
'@context': 'https://schema.org',
|
|
'@type': 'Article',
|
|
mainEntityOfPage: {
|
|
'@type': 'WebPage',
|
|
'@id': url,
|
|
},
|
|
headline: title,
|
|
image: featuredImages,
|
|
datePublished: publishedAt,
|
|
dateModified: modifiedAt,
|
|
author: {
|
|
'@type': 'Person',
|
|
name: siteMetadata.author,
|
|
},
|
|
publisher: {
|
|
'@type': 'Organization',
|
|
name: siteMetadata.author,
|
|
logo: {
|
|
'@type': 'ImageObject',
|
|
url: `${siteMetadata.siteUrl}${siteMetadata.siteLogo}`,
|
|
},
|
|
},
|
|
description: summary,
|
|
}
|
|
|
|
return (
|
|
<>
|
|
<Head>
|
|
<title>{`${title}`}</title>
|
|
<meta name="robots" content="follow, index" />
|
|
<meta name="description" content={summary} />
|
|
<meta property="og:url" content={`${siteMetadata.siteUrl}${router.asPath}`} />
|
|
<meta property="og:type" content="article" />
|
|
<meta property="og:site_name" content={siteMetadata.title} />
|
|
<meta property="og:description" content={summary} />
|
|
<meta property="og:title" content={title} />
|
|
{featuredImages.map((img) => (
|
|
<meta property="og:image" content={img.url} key={img.url} />
|
|
))}
|
|
<meta name="twitter:card" content="summary_large_image" />
|
|
<meta name="twitter:site" content={siteMetadata.twitter} />
|
|
<meta name="twitter:title" content={title} />
|
|
<meta name="twitter:description" content={summary} />
|
|
<meta name="twitter:image" content={featuredImages[0].url} />
|
|
{date && <meta property="article:published_time" content={publishedAt} />}
|
|
{lastmod && <meta property="article:modified_time" content={modifiedAt} />}
|
|
<link rel="canonical" href={`${siteMetadata.siteUrl}${router.asPath}`} />
|
|
<script
|
|
type="application/ld+json"
|
|
dangerouslySetInnerHTML={{ __html: JSON.stringify(structuredData, null, 2) }}
|
|
/>
|
|
</Head>
|
|
</>
|
|
)
|
|
}
|