Last active
November 5, 2020 13:34
-
-
Save bzin/3aaef6e9044a4b1232cea21460de5053 to your computer and use it in GitHub Desktop.
SEO React component to use with Seomatic plugin in combination with Next.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Head from 'next/head' | |
import { parse } from 'node-html-parser' | |
// Utilitation function to deal with https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml | |
// See: https://gist.github.com/bzin/a348421f733ee177a943669956dcd6b9#file-createmarkup-js | |
import createMarkup from '../../utils/createMarkup' | |
const Seo = (props) => { | |
const metaTitleContainer = JSON.parse(props.metaTitleContainer).title || { title: '' } | |
const metaScriptContainer = JSON.parse(props.metaScriptContainer) | |
const metaLinkContainer = JSON.parse(props.metaLinkContainer) | |
const metaTagContainer = JSON.parse(props.metaTagContainer) | |
const metaJsonLdContainer = JSON.parse(props.metaJsonLdContainer) | |
let gTagElement, gTagScript | |
if ((metaScriptContainer.gtag && metaScriptContainer.gtag.bodyScript)) { | |
gTagElement = parse(metaScriptContainer.gtag.bodyScript) | |
gTagScript = ( | |
<script key="gtag-js" async src={gTagElement.querySelector('script').getAttribute('src')}/> | |
) | |
} | |
let googleTagManagerElement, googleTagManagerScript | |
if ((metaScriptContainer.googleTagManager && metaScriptContainer.googleTagManager.bodyScript)) { | |
googleTagManagerElement = parse(metaScriptContainer.googleTagManager.bodyScript) | |
googleTagManagerScript = ( | |
<noscript dangerouslySetInnerHTML={createMarkup(googleTagManagerElement.firstChild.firstChild.rawText)}/> | |
) | |
} | |
let facebookPixelElement, facebookPixelScript | |
if ((metaScriptContainer.facebookPixel && metaScriptContainer.facebookPixel.bodyScript)) { | |
facebookPixelElement = parse(metaScriptContainer.facebookPixel.bodyScript) | |
facebookPixelScript = ( | |
<noscript dangerouslySetInnerHTML={createMarkup(facebookPixelElement.firstChild.firstChild.rawText)}/> | |
) | |
} | |
let linkedInInsightElement, linkedInInsightScript | |
if ((metaScriptContainer.linkedInInsight && metaScriptContainer.linkedInInsight.bodyScript)) { | |
linkedInInsightElement = parse(metaScriptContainer.linkedInInsight.bodyScript) | |
linkedInInsightScript = ( | |
<script dangerouslySetInnerHTML={createMarkup(linkedInInsightElement.firstChild.innerText)}/> | |
) | |
} | |
// Create meta elements | |
const MetaElements = Object.keys(metaTagContainer).map((key, index) => { | |
if (metaTagContainer[key].length === 0) return false | |
return <meta key={key} property={key} content={metaTagContainer[key].content}/> | |
}) | |
// Create meta links | |
const MetaLinkElements = Object.keys(metaLinkContainer).map((key, index) => { | |
// @todo find a solution for multiple link properties like alternate | |
if (metaLinkContainer[key].length === 0 || metaLinkContainer[key].length > 1) return false | |
return <link key={key} type={metaLinkContainer[key].type} rel={metaLinkContainer[key].rel} | |
href={metaLinkContainer[key].href}/> | |
}) | |
// Create json ld | |
const MetaJsonLdElements = Object.keys(metaJsonLdContainer).map((key, index) => { | |
return <script key={key} type="application/ld+json" dangerouslySetInnerHTML={createMarkup(JSON.stringify(metaJsonLdContainer[key]))}/> | |
}) | |
// Add tracking scripts | |
const MetaScriptElements = Object.keys(metaScriptContainer).map((key, index) => { | |
if(!metaScriptContainer[key].script) return false | |
return <script key={key} dangerouslySetInnerHTML={createMarkup(metaScriptContainer[key].script)}/> | |
}) | |
return ( | |
<> | |
<Head> | |
<title key="title">{metaTitleContainer.title}</title> | |
{/* Add meta elements */} | |
{MetaElements} | |
{/* Add link elements */} | |
{MetaLinkElements} | |
{/* Favicon manifest */} | |
<link rel="apple-touch-icon" sizes="180x180" href="/static/images/favicon/apple-touch-icon.png"/> | |
<link rel="icon" type="image/x-icon" href="/static/images/favicon/favicon.ico"/> | |
<link rel="icon" type="image/png" sizes="32x32" href="/static/images/favicon/favicon-32x32.png"/> | |
<link rel="icon" type="image/png" sizes="16x16" href="/static/images/favicon/favicon-16x16.png"/> | |
<link rel="manifest" href="/static/images/favicon/site.webmanifest"/> | |
<link rel="mask-icon" href="/static/images/favicon/safari-pinned-tab.svg" color="#5bbad5"/> | |
<link rel="shortcut icon" href="/static/images/favicon/favicon.ico"/> | |
<meta name="msapplication-TileColor" content="#da532c"/> | |
<meta name="msapplication-config" content="/static/images/favicon/browserconfig.xml"/> | |
<meta name="theme-color" content="#ffffff"/> | |
{/* Add Json LD scripts */} | |
{MetaJsonLdElements} | |
{/* Tracking scripts */} | |
{gTagScript} | |
{MetaScriptElements} | |
</Head> | |
{/* Implement tracking scripts in `body` */} | |
{googleTagManagerScript} | |
{facebookPixelScript} | |
{linkedInInsightScript} | |
</> | |
) | |
} | |
export default Seo |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment