Adding sitemap.xml inside next-js website with MongoDB
Post by: Niraj Dhungana
Posted on: Nov 30 2021
#Next JS# sitemap# SEO
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.
Next JS have all the things
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
2
3
4
// pages/api/sitemap.xml.js
export default function handler(req, res) {
// here goes the logic
}
Handler for sitemap
Now we have the function and the file so let’s test this route if this works or not.
1
2
3
4
5
6
// pages/api/sitemap.xml.js
export default function handler(req, res) {
if (req.method !== "GET")
return res.status(404).json({ error: "route not found!" });
res.send("Ok I got this!")
}
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
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const BASE_URL = "https://ndpniraj.com/blogs";
function generateSitemap(slugs) {
return `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://ndpniraj.com/</loc>
</url>
<url>
<loc>https://ndpniraj.com/blogs</loc>
</url>
${slugs.map(({ slug }) => {
return `
<url>
<loc>${`${BASE_URL}/${slug}`}</loc>
</url>
`;
}).join("")}
</urlset>
`;
}
😵 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.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
export default async function handler(req, res) {
if (req.method !== "GET")
return res.status(404).json({ error: "route not found!" });
try {
// fetching all the post-slug from the db
await dbConnect();
const slugs = await Post.find({}).select("slug");
// Generating the XML sitemap with the posts slug
const sitemap = generateSiteMap(slugs);
res.setHeader("Content-Type", "text/xml");
// sending the XML to the browser
res.write(sitemap);
res.end();
} catch (error) {
res.send(JSON.stringify(error));
}
}
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