Gatsby
Up and Running with Gatsby: Taking Gatsby to Production

Solution: SEO Component

PRO

Here's how to extract an SEO component for React Helmet.

Let's extract our React Helmet into its own SEO component called SEO.js.

First, let's add an image path to our siteMetadata in gatsby-config.js:

// gatsby-config.js
siteMetadata: {
    title: "Marionberry Farm Lodge",
    description:
      "Marionberry Farm Lodge is your rustic Pacific Northwest getaway. Unplug from your phone and sit by a fire. Spend the day at a nearby lake. Join us for classes on everything from blacksmithing to gardening. Whatever you do, take a break from screens and relax!",
    author: "The Marionberry Farm Lodge Team",
    year: 2019,
    image: "images/blacksmith.jpg",
  },

Then, we can add that image to our Helmet in Layout.js:

<Helmet>
    <title>{data.site.siteMetadata.title}</title>
    <meta name="description" content={data.site.siteMetadata.description} />
    <meta name="image" content={data.site.siteMetadata.image} />
</Helmet>

Finally, in the video I demonstrate moving the Helmet and corresponding query into src/components/SEO.js. The code for SEO.js will be:

import React from "react"
import { Helmet } from "react-helmet"
import { useStaticQuery } from "gatsby"

export default () => {
  const data = useStaticQuery(graphql`
    query {
      site {
        siteMetadata {
          title
          description
          image
        }
      }
    }
  `)

  return (
    <Helmet>
      <title>{data.site.siteMetadata.title}</title>
      <meta name="description" content={data.site.siteMetadata.description} />
      <meta name="image" content={data.site.siteMetadata.image} />
    </Helmet>
  )
}

Don't forget to clean up Layout.js and use the new SEO component:

import React from "react"
import styled from "styled-components"
import Header from "../components/Header"
import Footer from "./Footer"
import NavBar from "./NavBar"
import SEO from "./SEO"

const Container = styled.div`
  margin: 3rem auto;
  max-width: 650px;
  padding: 0 1rem;
`

export default ({ children, noHeader }) => {
  return (
    <>
      <SEO />
      <Container>
        !noHeader && <Header />
        <NavBar />
         children
        <Footer />
      </Container>
    </>
  )
}

Note: There is a problem with the Thinkster JSX syntax highlighter: both children and !noHeader && <Header /> should be wrapped in curly braces ({ and }).

We've now got some basic SEO metadata on our site. You can go really far with this. I'd recommend looking into the Facebook OpenGraph tags and the Twitter Cards tags to continue learning about SEO and Gatsby. I've provided some links down below.