Why Make a React SEO Component
Here's some of the reasoning and detail that went into making the React SEO Component.
There wasn't a great deal I knew about Search Engine Optimization before I set about writing the Build a coding blog from scratch with Gatsby and MDX guide that I published last year.
I'd say I know a bit more now but I still feel it's a bit of a black art.
One of the main reasons I made the component to get around having to document the process of making an SEO component that needed to go into the Build a Blog guide. It was when I was getting toward the end of writing the guide when I realised that the SEO part of the site was quite involved.
To begin with I started looking around to see if anyone had created an SEO component for Gatsby and found a closed GitHub PR on seo from Dustin Schau with some great notes from Andrew Welch on SEO and a link to a presentation he did back in 2017, great stuff.
Gatsby SEO
Adding an SEO component to a Gatsby site is well documented and I, like a lot of other people developing in Gatsby took Jason Lengstorf's' lead with the example used on Marisa's site. I'd used this several times already so was familiar with how it worked. The example that captured my imagination however was from LekoArts in his Gatsby Starter Prismic example.
Open Graph
We all want to have the cool preview cards you see when someone shares a post on Twitter or LinkedIn. This is done with Facebook's Open Graph Protocol where you add in metadata tags that are picked up by Twitter, LinkedIn, etc. to display the image added in the tags.
I did some work on an internal project where I work which uses this to
display the og:image
URL from pages. I was familiar with OGP but not
entirely familiar with the whole adding metadata to the <head>
of a
site.
The component
Each time I wanted to add the SEO metadata to a site I had to go find a project that I had added it to in the past and jack the code from there and use it in the new project.
There was a lot of wiring things up involved, even when it's a lift and drop there's usually something slightly different in the props being passed to the metadata tags.
If you take a look at LeKoArts' example there are three files for Facebook, Twitter and the SEO.
Facebook has it's set of <meta>
tags that need to have data passed
to them:
1<Helmet>2 <meta property="og:locale" content={locale} />3 <meta property="og:url" content={url} />4 <meta property="og:type" content={type} />5 <meta property="og:title" content={title} />6 <meta property="og:description" content={desc} />7 <meta property="og:image" content={image} />8 <meta property="og:image:alt" content={desc} />9</Helmet>
Twitter has it's tags too:
1<Helmet>2 {username && <meta name="twitter:creator" content={username} />}3 <meta name="twitter:card" content={type} />4 <meta name="twitter:title" content={title} />5 <meta name="twitter:description" content={desc} />6 <meta name="twitter:image" content={image} />7 <meta name="twitter:image:alt" content={desc} />8</Helmet>
SEO has it's things as well
Then there's keeping Google sweet as well with structured data this is so Google can understand the contents of the page. I took LekoArts' lead on this as it was something I wasn't familiar with at all. LekoArts did a great job of putting all this together:
1<>2 <Helmet title={seo.title} titleTemplate={`%s | ${titleTemplate}`}>3 <html lang={siteLanguage ? siteLanguage : 'en'} />4 <link rel="canonical" href={pathname} />5 <meta name="description" content={seo.description} />67 {!article && (8 <script type="application/ld+json">9 {JSON.stringify(schemaOrgWebPage)}10 </script>11 )}12 {article && (13 <script type="application/ld+json">14 {JSON.stringify(schemaArticle)}15 </script>16 )}17 <script type="application/ld+json">18 {JSON.stringify(breadcrumb)}19 </script>20 </Helmet>21 <Facebook22 desc={seo.description}23 image={image}24 title={seo.title}25 type={article ? 'article' : 'website'}26 url={pathname}27 locale={siteLocale ? siteLocale : 'en_gb'}28 />29 <Twitter30 title={seo.title}31 image={image}32 desc={seo.description}33 username={twitterUsername}34 />35</>
There's a lot more to this but for the sake of brevity I'm adding what the component returns. This is largely unchanged in the the component I made but for a few variables added.
Make it a thing
I wanted to be able to yarn add
this rather than have to go pick out
the components from another project each time.
It was interesting trying to find how to do it, I didn't find a great deal of documentation out there.
I found this post with some example code on GitHub.
The initial release used Rollup with Babel preset for React which worked fine. I've since moved it to use TypeScript with the awesome TSDX for TypeScript package development.
Enjoy
There's still a lot to do with the component, currently I'm overwriting some of the tags in this project after writing a serverless function to generate Open Graph Images with Gatsby and Now which uses these tags:
1<meta property="og:image" content={ogImageUrl} />2<meta name="twitter:image:src" content={ogImageUrl} />
The defaults are empty strings or a default J Doe
so not great but
there is a lot to go in there and hopefully a lot more to learn from
it by me.