Skip to content

Instantly share code, notes, and snippets.

@bzin
Last active November 5, 2020 13:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bzin/3aaef6e9044a4b1232cea21460de5053 to your computer and use it in GitHub Desktop.
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
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