Sign post with multiple signs pointing in many directions

Redirects with Sanity, Gatsby & Netlify

August 4, 2020

At some point in the life of a website, it will undergo some changes, be that migration from an earlier system to a new or content restructuring and other updates. To avoid confusing users with dead ends when they follow stale links from around the web, you redirect them to the appropriate page with either a 301 status code – for permanently moved resources - or a 302 for resources that have temporarily moved.

The status code is essential for SEO purposes as the crawler hits the page by following the stale links. If it gets status code 301, it will report back and store the new page as the expected result. A 302 status code won't result in an updated index.

Ok, I think that's enough of background and reasoning. How about we get crackin' on setting up redirects with Sanity for a Netlify hosted Gatsby site?

Sanity schema

Let's start with identifying what attributes need to be in the Sanity schema.

  • A fromPath attribute, this is the original path (make it relative, i.e. without the https://yoursite.com part)
  • A toPath attribute, this is the new path (make that one relative as well)
  • A statusCode attribute, this is the type of redirect: permanent or temporary

That's it for this example if you have more complex requirements for your redirects, you can add whatever else you need based on your hosting provider. Now, let's build the schema.

redirects.js
// redirects.js
export default {
  name: "redirect",
  title: "Redirect",
  type: "document",
  fields: [
    {
      name: "fromPath",
      title: "From",
      description: "Original page path (without https://yoursite.com)",
      type: "string",
    },
    {
      name: "toPath",
      title: "To",
      type: "string",
    },
    {
      name: "statusCode",
      title: "Type",
      type: "string",
      validation: Rule => Rule.required(),
      options: {
        list: [
          { title: "Permanent", value: "301" },
          { title: "Temporary", value: "302" },
        ],
      },
    },
  ],
  preview: {
      select: {
      from: "source",
      to: "destination",
      type: "statusCode",
    },
    prepare(selection) {
      const { from, type } = selection
      return {
        title: `${from}`,
        subtitle: `${statusCode ? statusCode : "Unknown"}`,
      }
    },
  },
}

There is nothing special to note with the fromPath and toPath attributes. However, notice how the statusCode attribute has validation and options added. The validation attribute uses Sanity's built-in validation for required content. The options attribute defines a list of available selections and makes a distinction between what the editor sees (title) and what API requests return (value). By setting the options like that you make it easy for editors to select the type of redirect without needing to know the status code behind it.

The last bit prepares the preview in the format { title: <original path>, subtitle: <301/302> }.

Just import this schema in your schema.js (or if you're like me, schema.ts), and you're good to go with the Sanity portion of this guide. Make sure you deploy the GraphQL schema before you move on to the next step.

Create redirects in Gatsby

Gatsby has a way to create redirects; however, server redirects don't work out of the box with Gatsby, meaning the redirects that Gatsby's build process creates are only client-side redirects. While most of your users wouldn't notice the difference, search engine crawlers most certainly will.

There is a plugin that creates Netlify redirects automatically when you use the built-in Gatsby redirect action linked above. It also provides a couple of extra attributes, out of which you will at least use the statusCode.

Go ahead and install the Netlify plugin in your Gatsby project and add it to the plugins array in gatsby-config.js.

bash
npm i -S gatsby-plugin-netlify
gatsby-config.js
plugins: [
  `gatsby-plugin-netlify`,
  // your other plugins
]

Before you can build the redirects, however, you need to query them. Open your gatsby-node.js file and look for your function that creates pages. If you don't have one, you can create it by adding a named export called createPages (exports.createPages). Have a read of the Gatsby documentation in case you need a refresher on how the createPages function works.

Take a look at the GraphiQL interface for Gatsby to get the GraphQL query you need for the redirects, but it should be something like this:

md
allSanityRedirect {
  nodes {
    toPath
    fromPath
    statusCode
  }
}

Notice how I added redirects: in front of the query? It changes the name of the property on the result object.

Open gatsby-node.js and add the GraphQL query. You're now going to use the built-in actions from Gatsby and access the createRedirect action.

gatsby-node.js
const { createRedirect } = actions;

Loop over the redirects from the GraphQL query and use the createRedirect action to pass the redirect to the Netlify plugin that creates a _redirects file for you.

gatsby-node.js
result.data.redirects.nodes.forEach((redirect) => {
  createRedirect({
    fromPath: redirect.fromPath,
    toPath: redirect.toPath,
    statusCode: redirect.statusCode
  })
})

Commit your changes, push to the production branch and let Netlify take care of the rest. When the build is complete, go over to your site and test the redirects. Notice that you get 301 and 302 status codes for the expected redirects.

Conclusion

You can extend the above however you like. For example, I created a CSV import in the Sanity dashboard that let clients upload a CSV file with all the redirects. They were then automatically imported in Sanity and built using Netlify.

We later switched our hosting to Firebase, which lacks a plugin to build the redirects paths. We fixed that by rewriting the firebase.json file with the redirects in the gatsby-node.js file.

With Sanity, all these things become a breeze and allow you the flexibility to build the redirects for the hosting provider of your choice.