Published on

How to Redirect in Gatsby without Using Any Plugin

Authors

Let's say you want to update slug (URL) for one of your blog post in Gatsby.

Updating it is pretty straight forward. You just need to open up your blog post's markdown in your favourite text editor and update the slug meta.

That's it right? Well, not exactly.

The issue is that your old URL will be broken and would throw 404 error if someone visits that URL.

That's a huge issue in terms of SEO and user experience. CMS like WordPress handles redirection of the old URL to the new URL automatically. However, in Gatsby we need to handle it manually.

Initially, I was trying out gatsby-redirect-from plugin for my blog but it didn't work as expected (maybe because I've /blog prefix for my blog post)

And so I decided to handle the redirection manually by using createRedirect API which creates client-side redirects

Let's get started

Step #1: Add redirect_from urls in post's meta

Basically in our blog post's meta, we'll have the old URLs which we'll later query and perform redirection.

For the sake of simplicity I'm naming the tag as redirect_from feel free to change it to whatever you want.

Here's an example of how it look likes

Step #2: Creating client-side redirection template

// ./src/template/redirect-page.js
// Based on https://pantaley.com/blog/Creating-client-side-page-redirect-in-GatsbyJS-without-using-plugins/
import React from 'react';
import Helmet from 'react-helmet';
import { StaticQuery, graphql } from 'gatsby';

export default props => {
    return (
        <StaticQuery
            query={graphql`
        query {
          site {
            siteMetadata {
              siteUrl
            }
          }
        }
      `}
            render={data => {
                return (
                    <Helmet>
                        <meta
                            http-equiv="refresh"
                            content={`0;url=${data.site.siteMetadata.siteUrl}${props.pageContext.redirect}`}
                        />
                    </Helmet>
                );
            }}
        />
    );
};

Step #3: Creating client-side redirection template

// ./src/utils/custom-redirect-from.js
const path = require(`path`)

// https://github.com/kremalicious/gatsby-redirect-from/blob/main/src/gatsby-node.js
function customRedirectFrom(post, createRedirect, createPage) {
    const redirectPageTemplate = path.resolve('./src/templates/redirect-page.js')
    // For all posts with redirect_from frontmatter,
    // extract all values and push to redirects array
    const redirects = []
    if (post.node.frontmatter.redirect_from) {
        redirects.push({
            from: `${post.node.frontmatter.redirect_from}`,
            to: `/${post.node.fields.slug}`
        })
    }

    redirects.forEach(redirect => {
        createRedirect({
            fromPath: redirect.from,
            toPath: redirect.to,
            isPermanent: true,
            redirectInBrowser: true
        })

        createPage({
            path: redirect.to,
            component: redirectPageTemplate,
            context: {
                redirect: redirect.to
            }
        });
    })


}

module.exports = customRedirectFrom

Step #4: Querying redirect_from and creating client side redirections

Now we need query redirect_from and call our custom function customRedirectFrom in createPages (gatsby-node.js)

Make sure to redirect_from while querying posts like this

// gatsby-node.js
exports.createPages = async ({ graphql, actions }) => {
  const { createPage, createRedirect } = actions

  // ... GraphQL query (refer above image) ...

  // Create blog posts pages.
  const posts = result.data.allMarkdownRemark.edges
  posts.map((post, index) => {
    createPage({
      path: post.node.fields.slug,
      component: blogPost,
      context: {
        slug: post.node.fields.slug,
      },
    })

    // Client side redirections
    customRedirectFrom(post, createRedirect, createPage)
  })
}

Step 5: Server side redirections

Depending on what hosting provider you use, you may need to use Gatsby plugin to handle the redirections

That's it. Hope it helps :)

Reference