Create a dynamic sitemap with Next.js



Mazen Mohamed
created at: ,  updated at: tags: sitemap, next.js
Create a dynamic sitemap with Next.js

If you're building a Next.js site or app that needs to be visible to search engines like google, bing, and other search engines, a sitemap is essential especially if it has many pages that you want to be indexed.

What is a sitemap

A sitemap is a map of the URLs on your site and makes it easier for search engine crawler bots to index your content, and increase your likelihood for ranking in search results.

browsers and search engines anticipate our sitemap being returned as an XML file

What will we use?

In Next.js we can rely on:

  • The built-in router.

  • [ "getServerSideProps" ] function provided by Next.js.

  • basic data fetching (for dynamic content).

  • installing [ "sitemap" ] more about it here package by npm/yarn, and use it with [ "stream" ] package provided by a node to easily build the XML Content.


Let's start the Work!

in your [ "/pages" ] directory at the root folder create a file named [ "sitemap.xml.js" ] and add the following to it.

Next.js will automatically create a route in our app at /sitemap.xml which is the location where browsers and search engine crawlers expect our sitemap to live.

Why is it an empty returned function you ask?

because we don't want to render a component at the URL.

Instead we will use [ "getServerSideProps" ] and build the XML content and return it as [ "text/xml" ]

let's continue.

First, in your terminal navigate to the root component of your project and type [ "npm I sitemap" ]

in the [ "/pages/sitemap.xml.js" ] do as the following:

Now, What happened?

  1. Instead of returning an object of props from getServerSideProps We will override it.

  2. We built the [ "links" ] array that we will push an object with [ "url" ], [ "changefreq" ], [ "priority" ] to it

  3. Create a stream to write to and add the [ "hostname" ] to it.

  4. Set the Content-Type header of the response to `text/XML.

  5. Write the response body and end the request.

if we remove the [ "return { props: {}, };" ] Next.js will throw an error at us

Congratulations now if you start your development server by typing [ "npm run dev" ] and in your browser and go to [ "localhost:3000/sitemap.xml" ] you will get the following:

In terms of what we're returning here we return the XML content expected by a web browser (or search engine crawler) when reading a sitemap.

  • For each URL in our site that we want to add to our map, we add the [ "<url></url>" ] tag.

  • Placing a [ "<loc></loc>" ] tag inside that specifies the location of our URL.

  • The [ "<lastmod></lastmod>" ] tag specifies when the content at the URL was last updated.

Time is in ISO-8601 string If you have a date available for when these pages were last updated, it's best to be as accurate as possible with this date and pass that specific date here

  • The [ "<changefreq></changefreq>" ] tag specifies how frequently the content at the URL is updated.

We're setting a sensible default of monthly, but this can be any of the following:

  • never
  • yearly,
  • monthly
  • weekly
  • daily
  • hourly
  • always
  • And a [ "<priority></priority>" ] tag to specify the importance of the URL (which translates to how frequently a crawler should crawl that page).

we set a base of 1.0 (the maximum level of importance). If you wish to change this to be more specific, this number can be anything between 0.0 and 1.0 with 0.0 being unimportant, 1.0 being most important.

Adding paths dynamically to the sitemap

Let's say we have a dynamic path like [ "profile/[user_name_id]" ] or [ "article/[slug]" ] how can we add them to the sitemap without adding them manually every single time.

Super easy barely an unconvinced

I have built a function to return the [ "user_name_id" ] and another one to return the [ "slug" ] needed from the database and put it in the [ "/lib" ] directory in the root project.

Create the functions and put them were ever you like and use the path to it to export the functions

example for the [ "user_name_id" ] function:

and now in [ "page/sitemap.xml.js" ] we will import them:

And now when we visit [ "localhost:3000/sitemap.xml" ] in the browser we get: