Adding sitemap.xml inside next-js website with MongoDB

Adding sitemap.xml inside next-js website with MongoDB

By: Niraj Dhungana

Nov 30 2021

#Next JS# sitemap# SEO

Share:

There are lots of posts available on the web to teach you what a sitemap is and why it is important? So, here in this post I will not waste your time and directly show you how we can add sitemap.xml inside our next-js website.

I already have a post on how I made this website on which you are reading this post. This website is made with next-js and some other tools. Which you will find on the post.

And if you visit this link "https://ndpniraj.com/api/sitemap.xml" you will see the sitemap of this website. So, let’s see how we can add this same thing inside your next-js website.

We already know that we can add both frontend and backend code inside next-js itself. So, we will use the api folder to add sitemap related code.

Here I am using a blog website for this example and we will fetch links that we want to add inside the search console from the MongoDB database where we are storing all the blog posts.

You can use this example and fetch the links from your database whatever you are using. At the end we only need our xml file which we can submit to Google or Bing.

First create a file sitemap.xml.js inside pages/api. Then export a function called handler with the export default keyword. Inside this file we can add our backend code.

1// pages/api/sitemap.xml.js
2export default function handler(req, res) {
3 // here goes the logic
4}
5

Handler for sitemap

Now we have the function and the file so let’s test this route if this works or not.

1// pages/api/sitemap.xml.js
2export default function handler(req, res) {
3   if (req.method !== "GET")
4     return res.status(404).json({ error: "route not found!" });
5	res.send("Ok I got this!")
6}
7

Here inside this method we are checking if the request type is other than GET. We are sending 404 not found. But if the request type is GET then we are sending this message (line number 5).

Alert: If you don’t know about express js then you may feel difficulty here.

Now you can visit http://localhost:3000/api/sitemap.xml. If you saw the message you are sending from inside the handler method. Then congratulations, it’s a good sign.

Let’s create another method inside this same file where we will format our sitemap.xml file. I will call this function generateSitemap.

1const BASE_URL = "https://ndpniraj.com/blogs";
2function generateSitemap(slugs) {
3  return `<?xml version="1.0" encoding="UTF-8"?>
4   <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
5   <url>
6        <loc>https://ndpniraj.com/</loc>
7   </url>
8   <url>
9        <loc>https://ndpniraj.com/blogs</loc>
10   </url>
11
12     ${slugs.map(({ slug }) => {
13         return `
14       <url>
15           <loc>${`${BASE_URL}/${slug}`}</loc>
16       </url>
17     `;
18       }).join("")}
19   </urlset>
20 `;
21}
22

😵 Okay-Okay I got it, let me explain what is happening inside this function. It’s a xml template which we will use to create our sitemap.xml file.

If you notice on line number 6 and 9 I have two urls of my website. These are the urls which I know will be there. Also at the same time I know that I want to index them on google.

You can add the urls of your website like the same. Which you want to index on the search console like Google or Bing.

Then I am expecting this parameter called slugs. These will be the slugs or endpoints of all the blog posts I want to index. Which I will fetch from my MongoDB (database).

You may have some other things like id of your post, name or other endpoint of the url. But if you don't have other endpoints then you can simply use remove the code from line number 12 to 18.

To complete the url I have a variable called BASE_URL. Using which I am creating the actual url inside that map method. Which will be indexed on the search console.

Fetching records from DB

Now we have the template ready, let's write some code to fetch those slugs from the DB and finish the process.

1export default async function handler(req, res) {
2  if (req.method !== "GET")
3    return res.status(404).json({ error: "route not found!" });
4  try {
5    // fetching all the post-slug from the db
6    await dbConnect();
7    const slugs = await Post.find({}).select("slug");
8
9    // Generating the XML sitemap with the posts slug
10    const sitemap = generateSiteMap(slugs);
11
12    res.setHeader("Content-Type", "text/xml");
13
14    // sending the XML to the browser
15    res.write(sitemap);
16    res.end();
17  } catch (error) {
18    res.send(JSON.stringify(error));
19  }
20}
21

Inside this final method first we have the code to connect our database. You can check out this post if you want to know how you can connect to MongoDB using mongoose inside next-js.

Then I am fetching all the posts from the database and selecting only slug. Now this will give the entire posts in an array like this [{ _id: ObjectId, slug: ‘post-slug’ }, {...}]

And if you notice earlier that is why I am using the destructuring syntax to destructure slug inside the map method of generateSitemap.

Then the rest of the code is self explanatory. First we need to set the header to notify the search console that the response is in xml format. And we are sending the sitemap and ending the response.

In this process if anything goes wrong try catch block will handle.

Now visit localhost sitemap api link. If get the result you want then you can publish your website and submit the sitemap url to the search console. yourwebsite.com/api/sitemap.xml

author

Niraj Dhungana

I hope you enjoyed reading this post and learned something new. If not then tell me how can I improve. @ndpniraj