NextJS build error when slug ends with .html for dynamic routes

I have been working on converting a massive WordPress site (20K posts) to NextJS. Every post on this old site has .html in the URL and we have to keep the same URL structure.

A Simple Fix

One simple hack would be using nextjs rewrites.

module.exports = {
  async rewrites() {
    return [
      {
        source: "/:slug*.html", // Old url with .html
        destination: "/:slug*", // Redirect without .html
      },
    ];
  },
}

You have to add this in your next.config.js file and it will redirect.

Well as you can see the above method is not a fix it’s just a workaround.

How I fixed this

By default, we know that nextjs creates .html pages for all the static pages. So we just have to create the page and if you want to add .html in the end then it will work automatically.

import Layout from "@components/Layout";
import getPostDetails from "@lib/wordpress/post/getPostDetails";
import getPostPaths from "@lib/wordpress/post/getPostPaths";
import BlogSection from "@components/pages/blog/BlogSection";

export default function BlogPage({postDetails}) {
  return (
    <Layout>
      <BlogSection
        postDetails={postDetails}
      />
    </Layout>
  );
}
export async function getStaticProps({ params: { slug } }) {
  // slug=["nextjs","how-to-add-an-rss-feed-to-your-next-js-wordpress-site"]
  const postSlug = slug[slug.length - 1];
  const containHtml = postSlug.includes(".html");
  const querySlug = containHtml ? postSlug.slice(0, -5) : postSlug;
  const postDetails = await getPostDetails(querySlug);

  if (!postDetails) {
    return {
      notFound: true,
    };
  }

  return {
    props: { postDetails, key: postSlug },
    revalidate: 60,
  };
}
export async function getStaticPaths() {
  const postPaths = await getPostPaths();
  // [{
  //   id:'someid',
  //   uri:'/nextjs/how-to-add-an-rss-feed-to-your-next-js-wordpress-site.html'
  // },...]
  const paths = postPaths.map((post) => post.uri.slice(0, -5));
  // ["/nextjs/how-to-add-an-rss-feed-to-your-next-js-wordpress-site",...]
  return {
    paths,
    fallback: "blocking",
  };
}

I have added few comments in the code that will help you understand how it works. You can see a working example here.

Stay safe and well. 🙂 Feel free to reach out to me if you have any questions.

Dipankar Maikap

Dipankar Maikap

I'm a freelance web developer. I work out of Kolkata, India. My favorite number is 77.

Leave a Reply

Your email address will not be published. Required fields are marked *