Creating a dynamic sitemap for Next.js & MDX

August 8, 2023 (1y ago)

Sitemaps are a vital tool for websites of any size. They provide a roadmap of your website's content, making it easier for search engines to find and index your web pages. This can lead to better SEO, ultimately making your site more visible to your potential users.

As your company grows, it is likely you will need to dynamically create a sitemap, especially if you are adding new pages often. This article focuses on how you can do this with a Next.js MDX project.

Getting Started

For this example, you will need to install the following dependencies:

  • fs for file system operations.
  • globby for pattern matching and file searching.
  • sitemap for sitemap generation.

You can install them with the following command:

pnpm add fs globby sitemap

Next, we will put the following code in the scripts folder. Your project should look like this:

my-app/
├─ scripts/
  ├─ generate-sitemap.js
├─ public/
├─ src/
├─ .gitignore
├─ package.json
const fs = require("fs");
const globby = require("globby");
const { SitemapStream, streamToPromise } = require("sitemap");

async function generateSitemap() {
  const pagesPath = `${process.cwd()}/src/pages`;

  const pages = await globby([
    `${pagesPath}/**/*.{js,ts,jsx,tsx,mdx}`,
    "!**/[_]*.{js,ts,jsx,tsx,mdx}",
    "!**/api",
  ]);

  const urls = [];

  for (const pagePath of pages) {
    const shortPath = pagePath
      .replace(pagesPath, "")
      .replace(/\/index\.([tj]sx?|mdx)$/, "")
      .replace(/\.([tj]sx?|mdx)$/, "");

    const url = `${shortPath === "" ? "/" : shortPath}`;

    urls.push({
      url,
      changefreq: "daily",
      priority: 0.7,
    });
  }

  const stream = new SitemapStream({ hostname: "https://domain.com" });

  urls.forEach((url) => stream.write(url));

  stream.end();

  const sitemap = await streamToPromise(stream).then((sm) => sm.toString());
  fs.writeFileSync("./public/sitemap.xml", sitemap);
  console.log(`Generated sitemap.xml`);
}

generateSitemap();

Note: Replace https://domain.com with your own domain.

You can test this by running

node scripts/generate-sitemap.js

Now that you have got that working, you will want to automatically run it every time you deploy a new version. To do this, we need to slightly alter the package.json.

"scripts": {
"dev": "next dev -p 3001",
"build": "next build && node scripts/generate-sitemap.js",
"start": "next start",
"lint": "next lint",
}

As you can see, we have added the node scripts/generate-sitemap.js to the build command. When you deploy the site, this will run automatically and be updated when your new site goes live. You can see the final result by going to https://domain.com/sitemap.xml.

With these simple steps, you've enabled dynamic sitemap generation for your Next.js MDX project. This will not only aid in SEO but also provide a better user experience by allowing users to easily navigate through your well-structured content.