diff --git a/components/BlogPost.tsx b/components/BlogPost.tsx index f4090ec..eae9361 100644 --- a/components/BlogPost.tsx +++ b/components/BlogPost.tsx @@ -1,18 +1,21 @@ -import Head from 'next/head'; -import React, { useEffect } from 'react'; +import { useEffect } from 'react'; import { useDispatch } from 'react-redux'; +import { METADATA } from '../constants'; import { PageType, setPageType, setPostTitle } from '../state/navigation'; import { IPost } from '../types/cms'; -import { generateTitle } from '../utils/metadata'; import { Article } from '../components/article/Article'; +import CustomHead from './CustomHead'; + +interface Props { + post: IPost; +} // Parallax on bg as mouse moves -export default function BlogPost({ post, url }: { post: IPost; url: string }) { +export default function BlogPost(props: Props) { + const { post } = props; const dispatch = useDispatch(); - const pageTitle = generateTitle(post?.title); - const imageURL = post?.featureImage?.imageUrl; useEffect(() => { if (post) { @@ -23,28 +26,23 @@ export default function BlogPost({ post, url }: { post: IPost; url: string }) { return ( <> - - {pageTitle} - - - - - - - - - - {' '} - - - - - - +
diff --git a/components/CustomHead.tsx b/components/CustomHead.tsx new file mode 100644 index 0000000..550f9dd --- /dev/null +++ b/components/CustomHead.tsx @@ -0,0 +1,252 @@ +import { ReactElement } from 'react'; +import Head from 'next/head'; +import { useRouter } from 'next/router'; + +import METADATA, { generateTitle, IMetadata } from '../constants/metadata'; +import { isLocal } from '..//utils/links'; + +interface Props { + title?: string; + metadata?: IMetadata; +} + +export default function CustomHead(props: Props): ReactElement { + const router = useRouter(); + const { title, metadata } = props; + const pageTitle = generateTitle(title); + const pageUrl = `${METADATA.HOST_URL}${router.asPath}`; + const imageUrl = (() => { + if (!metadata?.OG_IMAGE?.URL) + return `${METADATA.HOST_URL}${METADATA.OG_IMAGE.URL}`; + if (metadata?.OG_IMAGE?.URL && isLocal(metadata.OG_IMAGE.URL)) { + return `${METADATA.HOST_URL}${metadata.OG_IMAGE.URL}`; + } else { + return `${metadata?.OG_IMAGE?.URL}`; + } + })(); + const tags = metadata?.TAGS ? metadata?.TAGS : METADATA.TAGS; + const renderTags = (() => { + const keywords = ( + + ); + if (metadata?.TYPE !== 'article') return keywords; + return ( + <> + {tags.map((tag, index) => { + return ( + + ); + })} + + {metadata?.PUBLISHED_TIME && ( + + )} + {keywords} + + ); + })(); + const renderLdJSON = (() => { + const ldjson = `{ + "@context": "https://schema.org", + "@graph": [ + { + "@type": "WebSite", + "@id": "${METADATA.HOST_URL}/#website", + "url": "${pageUrl}", + "name": "${METADATA.SITE_NAME}", + "description": "${METADATA.DESCRIPTION}" + }, + { + "@type": "ImageObject", + "@id": "${pageUrl}#primaryimage", + "url": "${imageUrl}", + "width": "${String( + metadata?.OG_IMAGE?.WIDTH ?? METADATA.OG_IMAGE.WIDTH, + )}", + "height": "${String( + metadata?.OG_IMAGE?.HEIGHT ?? METADATA.OG_IMAGE.HEIGHT, + )}" + }, + { + "@type": "WebPage", + "@id": "${pageUrl}#webpage", + "url": "${pageUrl}", + "inLanguage": "${METADATA.LOCALE}", + "name": "${pageTitle}", + "isPartOf": { "@id": "${METADATA.HOST_URL}/#website" }, + "primaryImageOfPage": { + "@id": "${pageUrl}#primaryimage" + }, + "datePublished": "${metadata?.PUBLISHED_TIME ?? ''}", + "description": "${METADATA.DESCRIPTION}" + } + ] + }`; + return ( +