oxen-website/components/CustomHead.tsx

253 lines
7.2 KiB
TypeScript

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 = (
<meta key="keywords" name="keywords" content={tags.join(' ')} />
);
if (metadata?.TYPE !== 'article') return keywords;
return (
<>
{tags.map((tag, index) => {
return (
<meta
key={`article:tag-${pageUrl}-${index}`}
property="article:tag"
content={tag}
/>
);
})}
<meta
key="article:section"
property="article:section"
content={metadata?.ARTICLE_SECTION ?? METADATA.TAGS[0]}
/>
{metadata?.PUBLISHED_TIME && (
<meta
key="article:published_time"
property="article:published_time"
content={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 (
<script
key={`ldjson-${pageUrl}`}
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: ldjson }}
/>
);
})();
return (
<Head>
<title key={pageTitle}>{pageTitle}</title>
<meta key="utf-8" charSet="utf-8" />
<meta
key="viewport"
name="viewport"
content="width=device-width, initial-scale=1.0, viewport-fit=cover"
/>
<meta
key="description"
name="description"
content={metadata?.DESCRIPTION ?? METADATA.DESCRIPTION}
/>
<meta
key="robots"
name="robots"
content="index,follow,max-snippet:-1,max-image-preview:large,max-video-preview:-1"
/>
<meta
key="googlebot"
name="googlebot"
content="index,follow,max-snippet:-1,max-image-preview:large,max-video-preview:-1"
/>
<meta key="og:url" property="og:url" content={pageUrl} />
<meta key="og:title" property="og:title" content={pageTitle} />
<meta
key="og:type"
property="og:type"
content={metadata?.TYPE ?? METADATA.OG_TYPE}
/>
<meta
key="og:description"
property="og:description"
content={metadata?.DESCRIPTION ?? METADATA.DESCRIPTION}
/>
<meta key="og:image" property="og:image" content={imageUrl} />
<meta
key="og:image:secure_url"
property="og:image:secure_url"
content={imageUrl}
></meta>
<meta
key="og:image:alt"
property="og:image:alt"
content={metadata?.OG_IMAGE?.ALT ?? METADATA.OG_IMAGE.ALT}
/>
<meta
key="og:image:width"
property="og:image:width"
content={String(metadata?.OG_IMAGE?.WIDTH ?? METADATA.OG_IMAGE.WIDTH)}
/>
<meta
key="og:image:height"
property="og:image:height"
content={String(metadata?.OG_IMAGE?.HEIGHT ?? METADATA.OG_IMAGE.HEIGHT)}
/>
<meta key="og:locale" property="og:locale" content={METADATA.LOCALE} />
<meta
key="og:site_name"
property="og:site_name"
content={METADATA.SITE_NAME}
/>
<meta
key="twitter:card"
name="twitter:card"
content="summary_large_image"
/>
<meta key="twitter:title" name="twitter:title" content={pageTitle} />
<meta
key="twitter:description"
name="twitter:description"
content={metadata?.DESCRIPTION ?? METADATA.DESCRIPTION}
/>
<meta key="twitter:image" name="twitter:image" content={imageUrl} />
<meta
key="twitter:site"
name="twitter:site"
content={METADATA.HOST_URL}
/>
<meta key="twitter:creator" name="twitter:creator" content="Oxen_io" />
<meta
key="apple-itunes-app"
name="apple-itunes-app"
content="app-id=1547745078"
/>
<meta
key="msapplication-TileColor"
name="msapplication-TileColor"
content={METADATA.MSAPPLICATION_TILECOLOR}
/>
<meta
key="theme-color"
name="theme-color"
content={METADATA.THEME_COLOR}
/>
{renderTags}
<link key="canonical" rel="canonical" href={pageUrl} />
<link
key="image/png32x32"
rel="icon"
type="image/png"
sizes="32x32"
href={METADATA.FAVICON.MEDIUM}
/>
<link
key="image/png16x16"
rel="icon"
type="image/png"
sizes="16x16"
href={METADATA.FAVICON.SMALL}
/>
<link
key="apple-touch-icon"
rel="apple-touch-icon"
sizes="180x180"
href={METADATA.FAVICON.APPLE_TOUCH_ICON}
/>
<link key="manifest" rel="manifest" href={METADATA.MANIFEST} />
<link
key="mask-icon"
rel="mask-icon"
href={METADATA.MASK_ICON.PATH}
color={METADATA.MASK_ICON.COLOR}
/>
<link key="shortlink" rel="shortlink" href={METADATA.HOST_URL} />
<link
key="/feed"
rel="alternative"
type="application/rss+xml"
href="/feed"
/>
<link
key="/feed/atom"
rel="alternative"
type="application/atom+xml"
href="/feed/atom"
/>
<link
key="/feed/json"
rel="alternative"
type="application/feed+json"
href="/feed/json"
/>
{metadata?.TYPE === 'article' && renderLdJSON}
</Head>
);
}