Search code examples
http-redirectnext.jsstaticserver-side-rendering

How to redirect a page in Next.js for static export


Background: I have a tag page in my content based website that shows links to the pages that their content is tagged with the tag. But it turns out that my tagging system had a problem and now I want to prune the pages. So I need to redirect tags that only have one post in them to the single post. The following is what I tried so far:

export async function getStaticProps(context: any) {

  const res = await fetch(`${API_URL}/post/?tag=${context.params.tag}`)
  const posts = await res.json()

  for (var i = 0; i < posts.length; i++) {
    posts[i].link = '/blog/post/' + posts[i].slug;
  }
 
  if (posts.length===1){
    return {redirect: {
      permanent: true,
      destination: posts[0].link,
    },
  }
  }
  return {
    props: {
      posts: posts,
    },
  }
}

The Problem: The solution works when I run next locally. But it fails when I want to export the project to static.

So what is the appropriate way of redirecting for the current situation that works in static mode.


Solution

  • When dealing with redirects in Next.js for static exports, you should use the redirects configuration in the next.config.js file. Unfortunately, you cannot use getStaticProps for redirects in a static export because it only runs at build time, and redirects need to work at runtime.

    Here's how you can set up redirects for your situation:

    In your next.config.js file, you can define the redirects using the redirects property. For your specific use case, you want to redirect tags that have only one post to a single post. Here's an example:

    // next.config.js file
    module.exports = {
      async redirects() {
        const res = await fetch(`${API_URL}/tags`); // Fetch a list of tags or your data source
        const tags = await res.json();
    
        const redirects = [];
    
        tags.forEach((tag) => {
          if (tag.posts.length === 1) {
            redirects.push({
              source: `/tags/${tag.slug}`,
              destination: `/blog/post/${tag.posts[0].slug}`, // Redirect to the single post
              permanent: true, // Use permanent redirects if appropriate
            });
          }
        });
    
        return redirects;
      },
    };