Programmatic redirects with Gatsby

Porting a blog to Gatsby is the perfect time to rethink your url structure. My previous blog implementation used Jekyll and used the default date structure. This resulted in ugly urls like 2020/12/12/name-of-post. With my new blog I wanted something flatter so the same post would instead live at /name-of-post.

However, it’s important to be a thoughtful web citizen and ensure that your previous urls redirect to the new path. With Gatsby, I decided to leverage frontmatter and the createRedirect utility.

This allows me to use frontmatter like the following:

title: Some random title
date: 2020-12-12
redirects:
  - /2020/12/12/some-random-title
  - /some/other/old/path

This way, from the context of the post, I can reference any old urls as a yaml array, and then handle the actual redirects programmatically during page creation for the post.

mdxPages.edges.forEach(({ node }) => {
  const {
    frontmatter: { path, redirects }
  } = node

  if (redirects) {
    redirects.forEach(fromPath => {
      createRedirect({
        fromPath,
        toPath: path,
        redirectInBrowser: true,
        isPermanent: true
      })
    })
  }

  createPage({
    path,
    context: node,
    component: PostPage
  })
})

Above, this code checks for the existence of redirects and creates a redirect for each one.

Lastly, we need to also add gatsby-plugin-meta-redirect to gatsby-config.js so that an HTML file is created for each created redirect on build. The HTML file consists of a meta tag to redirect to the new location.

This allows us to create redirects for a statically generated site without having to mess with routing at the network layer (like a redirects file for ZEIT’s Now or Netlify).