Search code examples
reactjslocationgatsbyreact-propsreact-helmet

Error while using Location prop in Gatsby Helmet


I'd like to add a class to the body tag containing the pathname. I think I should have access to the location prop and that I should be able to pass this. However location is being passed as null.

I'm using this as a resource : https://www.gatsbyjs.com/docs/location-data-from-props/

/**
 * SEO component that queries for data with
 *  Gatsby's useStaticQuery React hook
 *
 * See: https://www.gatsbyjs.org/docs/use-static-query/
 */

import React from "react"
import PropTypes from "prop-types"
import Helmet from "react-helmet"
import { useStaticQuery, graphql } from "gatsby"

const SEO = ({ description, lang, meta, title, location }) => {
  const mylocation = location.pathname;
  const { site } = useStaticQuery(
    graphql`
      query {
        site {
          siteMetadata {
            title
            description
          }
        }
      }
    `
  )

  const metaDescription = description || site.siteMetadata.description

  return (
    <Helmet
      htmlAttributes={{
        lang,
      }}
      title= "Hello"
      titleTemplate={'%s | ${site.siteMetadata.title}'}
      meta={[
        {
          name: 'description',
          content: metaDescription,
        },
        {
          property: 'og:title',
          content: mylocation,
        },
        {
          property: 'og:description',
          content: metaDescription,
        },
        {
          property: 'og:type',
          content: 'website',
        },
      ].concat(meta)}
    >
    <body className={mylocation} />
  </Helmet>
  )
}

SEO.defaultProps = {
  lang: 'en',
  meta: [],
  description: '',
}

SEO.propTypes = {
  description: PropTypes.string,
  lang: PropTypes.string,
  meta: PropTypes.arrayOf(PropTypes.object),
  title: PropTypes.string.isRequired,
  location: PropTypes.string,
}

export default SEO

When rendering this page -> http://localhost:8000/about/ I expect to see mylocation = /about

Instead I see

Error in function SEO in ./src/components/seo.js:14
Cannot read property 'pathname' of undefined

./src/components/seo.js:14

Why is my location prop undefined?

Is there a better way to add a unique class or ID to each page?


Solution

  • location is a top-level property so it's only available in page components, as you can see in the docs:

    the location prop is passed to any page component and represents where the app is currently, where you’d like it to go, and other helpful information.

    So, to use it in the SEO component you will need to lift it down from any page component such as:

    const AboutMePage = ({ location, otherProps }) => {
    
        return <Layout>
          <SEO location={location} 
               description={`Some description`}
               lang={`Some lang`}
               meta={`Some meta`}
               title={`Some title`} />
           ...
        </Layout>
    
    }
    

    And so on for the rest of the pages.

    If you want to avoid code-breakings you can use a default value in case you miss passing the props down like:

    const SEO = ({ description, lang, meta, title, location="some default value" }) => {}