A quick and easy guide to creating a sitemap for a Next.js site

Let's learn how to quickly create a sitemap for our Next.js site so we can improve our SEO performance.

A quick and easy guide to creating a sitemap for a Next.js site
Photo by NASA / Unsplash

If you're looking to generate sitemaps for your Next.js website, the next-sitemap npm package is a great tool to help you with that. In this tutorial, I'll guide you through the process of using this package and explain why you would want to use it.

Why Use next-sitemap?

Sitemaps are essential for search engine optimization (SEO) as they help search engines discover and index the pages on your website. By using the next-sitemap package, you can easily generate sitemaps for your Next.js website, ensuring that search engines can crawl and index your pages effectively.

Installation

To get started, you need to install the next-sitemap package. Open your terminal and run the following command:

yarn add next-sitemap

Create a Config File

The next-sitemap package requires a basic config file named next-sitemap.config.js in the root directory of your project. This file will contain the configuration options for generating your sitemaps. Here's an example of a basic config file:

/** @type {import('next-sitemap').IConfig} */
module.exports = {
  siteUrl: process.env.SITE_URL || 'https://example.com',
  generateRobotsTxt: true, // (optional)
  // ...other options
};

Make sure to replace 'https://example.com' with the base URL of your website. You can also customize other options as needed.

Building Sitemaps

To build the sitemaps, you need to add a postbuild script in your package.json file. Open the package.json file and add the following script:

{
  "build": "next build",
  "postbuild": "next-sitemap"
}

This script tells Next.js to run the next-sitemap command after the build process is complete.

Custom Config File

If you want to use a custom config file instead of the default next-sitemap.config.js, you can specify it when running the build command. For example:

{
  "build": "next build",
  "postbuild": "next-sitemap --config awesome.config.js"
}

This allows you to have different configuration files for different environments or purposes.

Building Sitemaps with pnpm

If you're using the pnpm package manager, you need to create a .npmrc file in the root of your project to enable the postbuild step. Add the following line to the .npmrc file:

enable-pre-post-scripts=true

This ensures that pnpm runs the postbuild script defined in your package.json.

Index Sitemaps (Optional)

Starting from version 2.x of next-sitemap, the sitemap.xml file will be the Index Sitemap, which contains URLs of all other generated sitemap endpoints. If you have a small or hobby site that doesn't require an index sitemap, you can turn off index sitemap generation by setting generateIndexSitemap: false in your next-sitemap config file.

/** @type {import('next-sitemap').IConfig} */
module.exports = {
  siteUrl: 'https://example.com',
  generateRobotsTxt: true,
  generateIndexSitemap: false,
};

Splitting Large Sitemap into Multiple Files

If your sitemap becomes too large, you can split it into multiple files for better organization. To do this, define the sitemapSize property in your next-sitemap.config.js file.

For example:

/** @type {import('next-sitemap').IConfig} */
module.exports = {
  siteUrl: 'https://example.com',
  generateRobotsTxt: true,
  sitemapSize: 7000,
};

In this example, when the number of URLs in a sitemap exceeds 7000, next-sitemap will create separate sitemap files (e.g., sitemap-0.xml, sitemap-1.xml) and an index file (e.g., sitemap.xml).

Configuration Options

Here are the available configuration options that you can use in your next-sitemap.config.js file:

Property Description Type
siteUrl Base URL of your website string
output Next.js output modes (check documentation) string
changefreq Change frequency of pages (default: daily) string
priority Priority of pages (default: 0.7) number
sitemapBaseFileName The name of the generated sitemap file before the file extension (default: "sitemap") string
alternateRefs Denote multi-language support by unique URL AlternateRef[]
sitemapSize Split large sitemap into multiple files by specifying sitemap size (default: 5000) number
autoLastmod Add the <lastmod/> property to the sitemap (default: true) boolean
exclude Array of relative paths (wildcard pattern supported) to exclude from the sitemap string[]
sourceDir Next.js build directory (default: ".next") string
outDir Directory where the generated files will be exported (default: "public") string
transform A transformation function that runs for each relative path in the sitemap async function
additionalPaths Async function that returns a list of additional paths to be added to the generated sitemap list async function
generateIndexSitemap Generate index sitemaps (default: true) boolean
generateRobotsTxt Generate a robots.txt file and list the generated sitemaps (default: false) boolean
robotsTxtOptions Options for generating the robots.txt file object

Please refer to the next-sitemap documentation for more details on each configuration option.

Custom Transformation Function

The transform option allows you to define a custom transformation function that runs for each relative path in the sitemap. This function can add, remove, or exclude paths or properties from the URL set. Here's an example:

/** @type {import('next-sitemap').IConfig} */
module.exports = {
  transform: async (config, path) => {
    // Custom function to ignore the path
    if (customIgnoreFunction(path)) {
      return null;
    }

    // Only create changefreq along with path
    if (customLimitedField(path)) {
      return {
        loc: path,
        changefreq: 'weekly',
      };
    }

    // Use default transformation for all other cases
    return {
      loc: path,
      changefreq: config.changefreq,
      priority: config.priority,
      lastmod: config.autoLastmod ? new Date

().toISOString() : undefined,
      alternateRefs: config.alternateRefs ?? [],
    };
  },
};

In this example, the custom transformation function checks if a path should be ignored or if it requires a limited set of properties. It returns null to exclude a specific path or returns an object with properties for other cases.

Additional Paths Function

The additionalPaths function allows you to dynamically add additional paths to the generated sitemap list. It is useful when you have a large list of pages but don't want to render them all. The function should return an array of objects, where each object represents an additional path. Here's an example:

/** @type {import('next-sitemap').IConfig} */
module.exports = {
  additionalPaths: async (config) => {
    const result = [];

    // Required value only
    result.push({ loc: '/additional-page-1' });

    // All possible values
    result.push({
      loc: '/additional-page-2',
      changefreq: 'yearly',
      priority: 0.7,
      lastmod: new Date().toISOString(),

      // Acts only on '/additional-page-2'
      alternateRefs: [
        {
          href: 'https://es.example.com',
          hreflang: 'es',
        },
        {
          href: 'https://fr.example.com',
          hreflang: 'fr',
        },
      ],
    });

    // Using transformation from the current configuration
    result.push(await config.transform(config, '/additional-page-3'));

    return result;
  },
};

In this example, the additionalPaths function adds three additional paths to the sitemap, each with different properties. You can customize this function based on your specific requirements.

Full Configuration Example

Here's an example of a next-sitemap.config.js configuration file with all available options:

/** @type {import('next-sitemap').IConfig} */
module.exports = {
  siteUrl: 'https://example.com',
  changefreq: 'daily',
  priority: 0.7,
  sitemapSize: 5000,
  generateRobotsTxt: true,
  exclude: ['/protected-page', '/awesome/secret-page'],
  alternateRefs: [
    {
      href: 'https://es.example.com',
      hreflang: 'es',
    },
    {
      href: 'https://fr.example.com',
      hreflang: 'fr',
    },
  ],
  transform: async (config, path) => {
    return {
      loc: path,
      changefreq: config.changefreq,
      priority: config.priority,
      lastmod: config.autoLastmod ? new Date().toISOString() : undefined,
      alternateRefs: config.alternateRefs ?? [],
    };
  },
  additionalPaths: async (config) => [
    await config.transform(config, '/additional-page'),
  ],
  robotsTxtOptions: {
    policies: [
      {
        userAgent: '*',
        allow: '/',
      },
      {
        userAgent: 'test-bot',
        allow: ['/path', '/path-2'],
      },
      {
        userAgent: 'black-listed-bot',
        disallow: ['/sub-path-1', '/path-2'],
      },
    ],
    additionalSitemaps: [
      'https://example.com/my-custom-sitemap-1.xml',
      'https://example.com/my-custom-sitemap-2.xml',
      'https://example.com/my-custom-sitemap-3.xml',
    ],
  },
};

Feel free to adjust the values based on your specific needs.

Generating Dynamic/Server-side Sitemaps

The next-sitemap package also provides APIs to generate server-side sitemaps. This is useful when you need to generate sitemaps dynamically from a content management system (CMS) or a custom data source.

There are two APIs available:

getServerSideSitemapIndex: Generates index sitemaps based on the provided URLs and returns an application/xml response. Supports Next.js route files (e.g., route.ts, route.js) starting from Next.js 13+.

getServerSideSitemap: Generates a sitemap based on field entries and returns an application/xml response. Supports Next.js route files (e.g., route.ts, route.js) starting from Next.js 13+.

To use these APIs, you can import them into your Next.js application and configure them according to your needs. For more information and examples, please refer to the next-sitemap documentation.

Typescript JSDoc

If you're using TypeScript, you can enhance your development experience by adding the following line of code in your next-sitemap.config.js file:

/** @type {import('next-sitemap').IConfig} */
module.exports = {
  // YOUR CONFIG
};

This line provides TypeScript autocomplete and type checking for the configuration options.

That's it! You're now equipped with the knowledge to use the next-sitemap npm package to generate sitemaps for your Next.js website. Happy coding and optimizing your website for search engines!

Subscribe or follow me on Twitter for more content like this!