Creating and managing redirects using NextJS and Sanity CMS

Share

When undertaking the task of rebuilding an existing website, one crucial item on your go-live checklist is ensuring that redirects are in place to avoid users encountering 404 errors from search results.

Choosing to reconstruct our site with the robust combination of Next.js for frontend development and Sanity for content management, we faced the challenge of managing redirects. This was particularly evident when dealing with numerous outdated pages that wouldn't be included in the new site.

To address this challenge, we've implemented a redirect schema, providing a streamlined solution for the efficient management of redirects.

Prerequisites

Before diving into the data import process, ensure that you have the Sanity CLI installed. If you haven't done this yet, download and install it by executing the following command:

Language: sh

npm install @sanity/cli

Once the CLI is installed, and environment variables are set up, you can start using the Sanity CLI. Before initiating the content import, it's wise to take a backup of your existing data. To do this, run the export command:

Language: sh

sanity dataset export staging ./staging_backup.tar.gz

Here, we're creating a full backup of the staging dataset and storing it in a compressed directory. The reverse operation would be:

Language: sh

sanity dataset import ../staging_backup.tar.gz staging

If you've been developing on a staging dataset and want to migrate everything to the live environment, replace “staging” with “production” or your live dataset's name:

Language: sh

sanity dataset import ../staging_backup.tar.gz production

Creating a Sanity document

To streamline the handling of redirects after switching sites, we've utilized the import command. For this purpose, we've created a redirect document containing source URL, destination URL, and whether it's a permanent redirect:

Language: typescript

import {defineField, defineType} from "sanity";
import {SanityDocument} from "@sanity/types";
 
export default defineType({
  name: 'redirect',
  title: 'Redirect',
  type: 'document',
  fields: [
    defineField({
    name: 'source',
    title: 'From',
    type: 'string',
  }),
  defineField({
    name: 'destination',
    title: 'To',
    type: 'string',
  }),
  defineField({
    name: 'permanent',
    title: 'Permanent',
    type: 'boolean',
    initialValue: () => true,
  }),
  ],
});
 
export type RedirectSchema = {
  source: string;
  destination: string;
  permanent: boolean;
} & SanityDocument;

With Next.js, we've implemented a method to fetch redirects and output them in the redirects section of next.config.js.

Language: typescript

// Code snippet for generating redirects in next.config.js
 
async function generateRedirects() {
const query = groq`
  *[_type == 'redirect'] {
    destination,
    source,
    permanent
  }
`;
return await client.fetch(query);
}
 
const nextConfig = {
  async redirects() {
    return generateRedirects();
  },
  // Additional configurations...
}

Adding URL's to Sanity

For efficient redirect management, we've created an NDJSON file of URLs from our old site. We recommend creating a CSV file and converting it to NDJSON for easier handling. There are a number of online tools which will do this for you but as we wanted to add an _id to each field we wrote a custom node script to convert the CSV to NDJSON.

Language: javascript

const fs = require('fs');
const csv = require('csvtojson');
const csvFilePath = ‘redirects.csv';
const ndjsonFilePath = ‘redirects.ndjson';
const csvtojson = new csv();
 
csvtojson.fromFile(csvFilePath).then((jsonArrayObj) => {
  function generateGUID() {
    return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
      const r = (Math.random() * 16) | 0;
      const v = c == 'x' ? r : (r & 0x3) | 0x8;
      return v.toString(16);
    });
  }
 
const jsonArrayWithGUIDs = jsonArrayObj.map(obj => ({
  ...obj,
  _id: generateGUID(),
}));
 
const ndjsonData = jsonArrayWithGUIDs.map(JSON.stringify).join('\n');
fs.writeFileSync(ndjsonFilePath, ndjsonData);
console.log('Conversion complete.');
});

To run the above code create a package.json file and put csvtojson as a dependency then npm install. After this you can put your redirects.csv in the same directory as the above file and assuming your file is called convertToNDJSON.js run:

Language: sh

node convertToNDJSON

Ensure the required fields, as defined in the Sanity schema, are present. It's advisable to include an _id; for the first import, you can omit it, allowing Sanity to generate it. For subsequent imports, include the _id to update fields rather than add duplicates.

Language: json

// Example NDJSON content
[
  {
    "_type": "redirect",
    "source": "/blog/new-website-boosts-city-college-peterborough-milestone-70th-anniversary-year/",
    "destination": "/blog",
    "permanent": "TRUE"
  }
  // Additional entries...
]

Importing the data

Once you have the NDJSON file, initiate the import process. The following command imports the redirects.ndjson file into the production dataset, replacing existing matches based on the given _id or creating new entries:

Language: sh

sanity dataset import redirects.ndjson staging --replace

After the import is complete, log in to the Sanity backend and verify that the data is present as expected.

If you're using the next.config.js redirects configuration similarly, consider rebuilding the project to ensure NextJS picks up the redirects.