Gatsby Helmet

Building meta tags

Gatsby Helmet

by John Vincent


Posted on September 20, 2019


For meta tags, Gatsby relies on react-helmet

Install

npm i --save gatsby-plugin-react-helmet

Add to gatsby-config.js in the plugins section

`gatsby-plugin-react-helmet`,

Implementation

The architecture I prefer is the expert pattern. Thus offload the functionality to an expert class SEO.jsx

import React from 'react';
import Helmet from 'react-helmet';

import { seoType } from '../types';

const SEO = ({ seo }) => (
	<>
		<Helmet title={seo.title}>
			<html lang={seo.lang} />
			<meta name="google-site-verification" content={seo.googleSiteVerification} />
			<meta name="description" content={seo.description} />
			<meta name="keywords" content={seo.keywords} />
			<meta name="author" content={seo.author} />

			<meta name="image" content={seo.image} />

			<script type="application/ld+json">{JSON.stringify(seo.schemaOrgJSONLD)}</script>

			<meta property="fb:app_id" content={seo.fbAppId} />

			{/* OpenGraph  */}
			<meta property="og:locale" content={seo.locale} />
			<meta property="og:type" content={seo.type} />
			<meta property="og:title" content={seo.title} />
			<meta property="og:description" content={seo.description} />
			<meta property="og:url" content={seo.url} />
			<meta property="og:image" content={seo.image} />
			<meta property="og:image:width" content="449" />
			<meta property="og:image:height" content="449" />

			{/* Twitter Card */}
			<meta name="twitter:card" content="summary" />
			<meta name="twitter:title" content={seo.title} />
			<meta name="twitter:description" content={seo.description} />
			<meta name="twitter:site" content={seo.twitterCreator} />
			<meta name="twitter:image" content={seo.image} />
			<meta name="twitter:creator" content={seo.twitterCreator} />

			<link rel="alternate" type="application/rss+xml" href={seo.seoFeed} />

			<base href={seo.baseUrl} />
		</Helmet>
	</>
);
SEO.propTypes = {
	seo: seoType.isRequired,
};

export default SEO;

Type checking

From ../types/index.js

export const seoType = PropTypes.shape({
	title: PropTypes.string.isRequired,
	description: PropTypes.string.isRequired,
	keywords: PropTypes.string.isRequired,

	author: PropTypes.string.isRequired,

	url: PropTypes.string.isRequired,

	lang: PropTypes.string.isRequired,
	locale: PropTypes.string.isRequired,

	type: PropTypes.string.isRequired,

	fbAppId: PropTypes.string.isRequired,

	image: PropTypes.string.isRequired,

	googleSiteVerification: PropTypes.string.isRequired,

	twitterCreator: PropTypes.string.isRequired,

	seoFeed: PropTypes.string.isRequired,

	schemaOrgJSONLD: requiredArrayType.isRequired,

	baseUrl: PropTypes.string.isRequired,
});

which provides some checking as well as a form of documentation.

Usage

seo is passed as a parameter. Class SEO doesn't care how it was constructed thus this component is reusable.