How to create Redirects in your Next.js Project


Basic Redirects in Next.js

Whether you run a blog or another application in Next.js, the chance is high that you will need to create redirects one day because parts of the application moved, but your outdated URLs are still published somewhere on the web. I recently moved the part of this blog that contains all blog posts from the path /posts to /blog. Since I posted some of my articles on Reddit, the old URLs are still generating traffic. To provide a better user experience, I wanted to redirect the links to the new path. For illustration purposes, I will initially show how to redirect single URLs, followed by further, more advanced options.

Redirecting a Single URL in Next.js

Redirecting a single URL in Next.js is reasonably straightforward. You simply return an async function called redirects in Next.js' config file next.config.js. The function returns an array containing objects, which declare the redirects. The objects have three properties that are required:

  • source: string that describes the URL to be redirected (patterns are possible, more on that later)
  • destination: string that describes where the redirect leads
  • permanent: boolean that determines the status code - true (308) tells search engines to cache the redirect indefinitely, and false (307) is a temporary redirect and will not be cached
module.exports = {
  async redirects() {
    return [
      {
        source: '/old-url-to-be-redirected',
        destination: '/new-path',
        permanent: true,
      },
    ]
  },
}

💡 In local development: restart the server to see your redirects in action!

Redirecting entire Paths in Next.js

Redirecting an entire path which is not nested (e.g., only has one layer) can be done by appending a slug (:path) that gets forwarded to the new path of the redirect. The name of the slug is arbitrary.

module.exports = {
  async redirects() {
    return [
      {
        source: '/old-path-no-nesting/:path',
        destination: '/new-path-no-nesting/:path',
        permanent: true,
      },
       {
        source: '/old-path-with-nesting/:path*',
        destination: '/new-path-with-nesting/:path*',
        permanent: true,
      },
    ]
  },
}

The first configuration matches all URLs directly under /old-path-no-nesting/, like /old-path-no-nesting/article-1, /old-path-no-nesting/article-2, etc. Matching nested URLs to capture all URLs under a path requires a *, which then matches /old-path-with-nesting/n/e/s/t/i/n/g and all other URLs under /old-path-with-nesting/. For more complicated matchings, Regex can be used, which can be found in the documentation of Next.js redirects.

Trivia: Why status codes 307 and 308 instead of 301 and 302?

301 (permanent) and 302 (temporary) used to be the status codes for handling redirects. However, many browsers executed a GET request on the redirected request, even if the initial incoming request was a POST request. Using the status codes 307 (temporary) and 308 (permanent) allows Next.js to prevent this and reuse the initial request method.