Home > References > SEO

Next js generate sitemap dynamically

Last updated : March 3, 2021

Creating a sitemap in Next js is no complicated task. In Next js, you can generate a dynamic sitemap without installing any additional libraries or npm packages. All you need is a js file in the Next js pages folder. Let's see how can we achieve this.

Sitemap structure

According to Google, there are three types of site maps.

  • XML
  • RSS
  • Text

Our focus will be on creating an XML sitemap. We will follow the below structure recommended by Google.

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="https://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://www.example.com/some-page-needs-attention</loc>
    <lastmod>2018-06-04</lastmod>
  </url>
</urlset>

JSON response for sitemap data

Since we create a dynamic sitemap, we have to get the required data by calling an API. The required data is the URL and last modified date of each page we intend to make searchable by search engines. Therefore, ideally, our API would return a list of URLs and corresponding modified dates for each URL. Something similar to the below JSON.

[{"url":"https://www.example.com","lastmod":"2020-12-21"},
{"url":"https://www.example.com/web/about","lastmod":"2020-12-01"},
{"url":"https://www.example.com/web/desclaimer","lastmod":"2020-12-01"},
{"url":"https://www.example.com/web/privacy","lastmod":"2020-12-01"}]

We will build our sitemap based on the above response JSON.

Creating sitemap.xml.js file

Now, let's create the sitemap file. Note that the search engines look for the site map in the root, i.e www.yoursite.com/sitemap.xml. Therefore, we name the file sitemap.xml.js so we can access it with sitemap.xml followed by the domain name. Make sure to place the sitemap.xml.js file directly in the Next js pages, making it accessible with the desired URL.

const Sitemap = () => {};
const toUrl = (route) =>
  `<url><loc>${route.url}</loc><lastmod>${route.lastmod}</lastmod></url>`;
  
const createSitemap = (urlList) => 
  `<?xml version="1.0" encoding="UTF-8"?>
    <urlset xmlns="https://www.sitemaps.org/schemas/sitemap/0.9">
    ${urlList.map((url) => toUrl(url)).join("")}
    </urlset>`;
	
export async function getServerSideProps({ res, req }) {      
	const siteMapJson = await fetch(`https://www.exampleapi.com/getsitemap`);
	const urlList = await siteMapJson.json();
	const sitemap = createSitemap(urlList);
	res.setHeader("Content-Type", "text/xml");
	res.write(sitemap);
	res.end();
	return { props: { results : {urlList}}}
};
export default Sitemap;

That's all to it. If your API returns a valid JSON, you can access your sitemap at https://www.yourdomain.com/sitemap.xml Now let's take a look at how all these work.

How does it work?

If you are in a hurry and just wanted to create a dynamic sitemap for your website, you can skip the below. If you are curious how the above code works, read on.

Next js server side rendering the sitemap

The method getServerSideProps({ res, req }) is executed on the node server. In this method, we call our API, generate the sitemap and set the sitemap to client response.

fetch(`https://www.mysiteapi.com/getsitemap`);
  const urlList = await siteMapJson.json();
  const sitemap = createSitemap(urlList);
  res.setHeader("Content-Type", "text/xml");
  res.write(sitemap);
  res.end();
  return { props: { results : {urlList}}}
};

Generate the sitemap with JSON

In lines 1 and 2, we get the URL list to generate the sitemap by calling the API. Therefore, the variable urlList holds the Json response listed above. Line 3 is where the sitemap is getting created by calling the createSitemap(urlList) method with the Json Url list.

const toUrl = (route) =>
  `<url><loc>${route.url}</loc><lastmod>${route.lastmod}</lastmod></url>`;
const createSitemap = (urlList) => 
  `<?xml version="1.0" encoding="UTF-8"?>
    <urlset xmlns="https://www.sitemaps.org/schemas/sitemap/0.9">
      ${urlList.map((url) => toUrl(url)).join("")}
    </urlset>`;

Sending the sitemap response to the client

The above code generates the sitemap and stores it in the variable sitemap as a string value. Now we have to send this to the client. The res.setHeader("Content-Type", "text/xml"); sets the response header to XML. This instructs the client to treat this response content as XML data. res.write(sitemap); and res.end(); writes the sitemap contents to the response. Note that it is important to use res.end(); when you use res.write();

Best practices for creating sitemaps

The purpose of a sitemap is to help search engines to crawl pages of your website. A sitemap is useful when pages end up without any internal links pointing to them, making them hard to find. A sitemap can also help search engines to understand your website structure. Below are some general guidelines to consider when you create a sitemap.

  • Use consistent, absolute URLs: If your site is at https://www.mysite.com, avoid using URLs like https://mysite.com.
  • Always place the sitemap in the root, so it can be accessed with https://www.mysite.com/sitemap.xml
  • Include only canonical URLs of your pages
  • If your site has a large number of pages, consider breaking up your sitemap into multiple sitemaps. Google's recommendation is a maximum of 50,000 URLs or 50MB per sitemap.
  • Ensure the sitemap is utf8 encoded.
  • Use <lastmod> appropriately to indicate the last modified date of each resource in the sitemap.

References

Lance
By: Lance
Lance is a software engineer with over 15 years of experience in full-stack software development.
Read more...

Leave a comment

No Comments