in

Gatsby: Custom 404 Page and React Helmet

Custom 404 Page

This one is pretty simple. In your pages directory create a page called 404.js and inside of that create a simple component for display. It could be anything but here is an example.

import React from "react"
import { Link } from "gatsby"

import Layout from "../components/layout"

const NotFound = () => {
  return (
    <Layout>
      <h1>Page not found</h1>
      <p>
        <Link to="/">Head home</Link>
      </p>
    </Layout>
  )
}

export default NotFound

That’s it. Congratulations.

Gatsby React Helmet

React Helmet is a reusable component that manages all the changes to the site head, such title, meta data etc. Gatsby has a sister component called gatsby-plugin-react-helmet which provides drop-in support for server rendering data added with React Helmet.

Once you have those two plugins installed you will create a new component head.js

import React from 'react'
import { Helmet } from 'react-helmet'

const Head = () => {
    return (
        <Helmet title="test title" />
    )
}

export default Head;

And into that we have passed one test prop. Then the goal is to get this component on every page. So starting with the index we would do the following.

import React from "react"

import Layout from '../components/layout';
import Head from '../component/head'

const IndexPage = () => {
  return (
    <Layout>
      <Head />
      <h1>Nick Coughlin</h1>
      <p>
        Welcome to the Home Page
      </p>
    </Layout>
  )
}

export default IndexPage

And it we run develop and visit the homepage we can see the test title in the head. The goal though is not to manually enter a title for every page, we want to generate these titles dynamically.

Dynamic Meta Data

A typical page title has a format similar to the-name-of-the-page | Sitename so we are going to follow that pattern here.

Back inside our head.js component, pulling in dynamic data means that we are going to be using graphql again, so we import that to pull in the site title from metadata, and then we simply pass that into our helmet component as a prop.

import React from 'react'
import { Helmet } from 'react-helmet'
import { useStaticQuery, graphql } from 'gatsby'

const Head = () => {
    const data = useStaticQuery(graphql`
        query {
            site {
                siteMetadata {
                    title
                }
            }
        }
    `)

    return (
        <Helmet title={data.site.siteMetadata.title} />
    )
}

export default Head;

If you need a refresher on where this site metadata lives, it’s inside the gatsby-config file. That covers the sitename, now we want to pull in the page title.

To do this we create a prop and pass it in to the Head component. Going back to our index.js we have our head component nested, and we add a prop called title to that. Now we can reference that prop.

import React from "react"

import Layout from '../components/layout';
import Head from '../components/head'

const IndexPage = () => {
  return (
    <Layout>
      <Head title='Home' />
      <h1>Nick Coughlin</h1>
      <p>
        Welcome to the Home Page
      </p>
    </Layout>
  )
}

export default IndexPage

And then going back to the head component we de-structure the title off props and pass it into Helmet.

import React from 'react'
import { Helmet } from 'react-helmet'
import { useStaticQuery, graphql } from 'gatsby'

const Head = ({ title }) => {
    const data = useStaticQuery(graphql`
        query {
            site {
                siteMetadata {
                    title
                }
            }
        }
    `)

    return (
        <Helmet title={`${title} | ${data.site.siteMetadata.title}`} />
    )
}

export default Head;

From there the process is simple. You just repeat the process of import Head component and add the Head component to every page, passing in a static title, and then for the blog post template you pass in a dynamic title, and now you’ve got dynamic titles on all your blog posts as well. Easy Peasy.

GitHub Repo

Ncoughlin: Gatsby-Bootcamp