Frontend developer focused on inclusive design

Next.js sitemap

Sitemap is like a map for search engines, guiding them through a website's content. It includes the website's URLs, updates, and the priority of each page. This map helps search engines find and organize website content.

While constructing a web application with Next.js, I needed a straightforward sitemap.xml. These notes are based on my experience, creating a basic sitemap functionality without additional packages.

Create sitemap.xml

There are different ways to create a sitemap in Next.js.

In these notes, the sitemap functionality uses App Route feature, which provides support for Route Handlers. These handlers make it possible to define custom request handlers for a given route.

The key file in this process is route.js.

This special file must be inside the app directory, more specifically in this case, inside the app/(seo)/sitemap.xml directory. Here (seo) is a route group, which allows to organize related routes together without changing the URL path.

/**
 * GET handler for generating sitemap.xml
 */
export function GET() {
  // Data contains all URLs that should be included in the sitemap
  const data = [
    {
      url: "https://www.recitop.com/",
      lastmod: new Date("May 19, 2023").toISOString(),
      changefreq: "daily",
      priority: "0.8",
    },
    {
      url: "https://www.recitop.com/create",
      lastmod: new Date("May 19, 2023").toISOString(),
      changefreq: "daily",
      priority: "1",
    },
  ];

  // Constructing sitemap from URLs
  let body = '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">';
  data.forEach((item) => {
    body += `
        <url>
          <loc>${item.url}</loc>
          <lastmod>${item.lastmod}</lastmod>
          <changefreq>${item.changefreq}</changefreq>
          <priority>${item.priority}</priority>
        </url>
      `;
  });
  body += "</urlset>";

  // Returning sitemap XML
  return new Response(body, {
    status: 200,
    headers: {
      "Cache-control": "public, s-maxage=31536000, stale-while-revalidate",
      "content-type": "application/xml",
    },
  });
}

Above is an example of route.js . This file contains the GET method which is in charge of generating the sitemap.

It does so by utilizing an array named data. This array holds several objects, each symbolizing a webpage that's part of the sitemap.

Every object holds four key details:

  • url: This represents the webpage's web address.
  • lastmod: This captures the most recent modification date of the URL. It takes advantage of JavaScript's Date object to create the date, and then automatically switches it to the ISO 8601 date format.
  • changefreq: This estimates how often the content of the webpage might change. It can be any of the following values: "always", "hourly", "daily", "weekly", "monthly", "yearly", and "never".
  • priority: This is a number between 0.0 and 1.0. It hints at how important the webpage is in comparison to others on the same website.

Using the data array, the structure of the sitemap.xml gets built. The properties of every object in data are added into an XML string. Then, the XML string becomes the response to any GET requests to /sitemap.xml. This is essentially the sitemap.

When a GET request is made, the response sent back to the client contains the sitemap, lets the client know that everything is OK (status 200), and provides some rules about how to cache the content and what sort of content it is.

Bear in mind this method creates a static sitemap. To make it dynamic, some modifications would be needed. This guide is a starting point for creating a basic sitemap.xml with Next.js, without any 3rd party packages.

Modify sitemap.xml

To modify sitemap.xml by adding new pages or changing existing ones, update the data array in the route.js file. Each page is represented by an object within this array.

For instance, to add a new /about page with the last modification date as March 27, 2023, add a new object to the data array:

const data = [
  // ...existing data
  {
    url: "https://www.recitop.com/about",
    lastmod: new Date("March 27, 2023").toISOString(),
    changefreq: "monthly",
    priority: "0.5",
  },
];

This object includes the url for the new page, the lastmod field indicating when it was last updated, changefreq which represents the estimated change frequency of the page content, and priority which indicates the importance of the page in relation to other pages on the site.

Save the file and redeploy the application for the changes to take effect.