Adding an XML map to a NextJS app

Adding an XML map to a NextJS app

February 25, 2024

When creating this blog using Sanity.io and NextJS 14, I realized there is no function to automatically create an XML Sitemap, and most of the online tutorial are slightly outdated as they don't take into consideration NextJS new app structure.

Here how I did for this blog:

1. Install the sitemap plugin

npm i sitemap

2. Create a new API endpoint to generate the sitemap on demand

In this case it will be stored in the /app/api/sitemap endpoint

3. The code itself. The important part is the function getAllArticles, which is the same as I use for other parts of the website to generate a list of all articles. This one can be customized depending on your needs

import { SitemapStream, streamToPromise } from "sitemap";
import { Readable } from "stream";
import { getAllArticles } from "@/utils/sanity";
import { PostType } from "@/types/post";

/**
 * Handles the GET request for the sitemap route.
 * Fetches all articles, generates links for each article, and returns the sitemap response.
 * @param request - The incoming request object.
 * @returns A Response object containing the sitemap response.
 */
export async function GET(request: Request) {
  // Fetch your pages here
  const posts = await getAllArticles();

  // Generate links for each post
  const links = posts.map((post: PostType) => ({
    url: `/post/${post.slug}`,
    changefreq: "daily",
    priority: 0.9,
  }));

  // Create a SitemapStream with the hostname
  const stream = new SitemapStream({ hostname: "https://vincent.taipei" });

  let response = "";

  // Convert the links to a readable stream and pipe it to the SitemapStream
  response = await streamToPromise(Readable.from(links).pipe(stream)).then(
    (data) => data.toString()
  );

  // Return the sitemap response
  return new Response(response, {
    status: 200,
    headers: {
      "Content-Type": "application/xml",
    },
  });
}

Bonus: the code comment and documentation were automatically generated through Copilot.