How to build a sitemap xml in Node js using Express

Create a sitemap in Node and Express framework for Search Engine Optimization

Jun 17, 2020
featured image

A good sitemap.xml will help you a lot in terms of SEO. It’s a nice starting point if you want to index your site. It’s just a standard XML file that search engines understand.

Can be as simple as this one:

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="">
You can see the complete list of tags definitions here:
Let’s code a Node.js web app using Express.js framework to expose an endpoint that prints a well-formed sitemap XML

Install Express

Install Express js globally to take advantage of Express generator
sudo npm install express -g
Run this command to generate a default Express structure
express --no-view --git node-sitemap-xml
You should see something like this. It could be different depending on your Express version.
create : node-sitemap-xml/
create : node-sitemap-xml/public/
create : node-sitemap-xml/public/javascripts/
create : node-sitemap-xml/public/images/
create : node-sitemap-xml/public/stylesheets/
create : node-sitemap-xml/public/stylesheets/style.css
create : node-sitemap-xml/routes/
create : node-sitemap-xml/routes/index.js
create : node-sitemap-xml/routes/users.js
create : node-sitemap-xml/public/index.html
create : node-sitemap-xml/.gitignore
create : node-sitemap-xml/app.js
create : node-sitemap-xml/package.json
create : node-sitemap-xml/bin/
create : node-sitemap-xml/bin/www
change directory:
cd node-sitemap-xml 

Install dependencies

npm install 

run the app

DEBUG=node-sitemap-xml:* npm start   
Enter to the created folder
cd node-sitemap-xml
Install dependencies
npm install
Let’s add a dependency to convert JavaScript objects to XML
npm install js2xmlparser --save

Add moment.js

Add Moment js as a dependency to deal with dates. Moment js it’s an awesome module to parse, format and manipulate dates. Strongly recommended
npm install moment --save
Create a new file called sitemap.js at the routes folder and paste this content.

sitemap.xml generation route

const express = require("express");
const router = express.Router();
const js2xmlparser = require("js2xmlparser");
const moment = require("moment");
 * It generates a standard sitemal.xml for SEO purposes
router.get("/", function(req, res, next) {
    try {
        //our records to index
        const records = getRecordsFromDataSource();
        const collection = [];
        let today = moment();
        today = today.format("YYYY-MM-DD");
        //add site root url
        const rootUrl = {};
        rootUrl.loc = "";
        rootUrl.lastmod = today;
        rootUrl.changefreq = "daily";
        rootUrl.priority = "1.0";
        rootUrl["image:image"] = {
            "image:loc": "s://",
                " Software development blog. Java, Node JS, Salesforce among other technologies",
        //add recipes urls
        for (let i = 0; i < records.length; i++) {
            const url = {};
            url.loc = records[i].url;
            url.lastmod = records[i].updated_at;
            url["image:image"] = {
                "image:loc": records[i].featured_image_url,
                "image:caption": records[i].description,
        const col = {
            "@": {
                xmlns: "",
                "xmlns:image": "",
            url: collection,
        const xml = js2xmlparser.parse("urlset", col);
        res.set("Content-Type", "text/xml");
    } catch (e) {
 * @return a collection to index (typically we'll get these records from our database)
function getRecordsFromDataSource() {
    //these records will have our own structure, we return as they are and later we convert them to the xml standard format
    //so let's just define two records hard-coded
    const record1 = {
        url: "",
            "Introduction A good practice in software development is to delegate as much heavy work as possible to background jobs",
        featured_image_url: "",
        updated_at: "2019-07-11",
    const record2 = {
        url: "",
        description: "A small site in Node.js using Express that will have one protected page Http auth basic prompt",
        featured_image_url: "",
        updated_at: "2019-07-11",
    return [record1, record2];
module.exports = router;

Basically, that code builds dynamically our sitemap XML.

  • First, it creates a block for the home page and then iterates on our records that can be a mix of different types of records such as recipes, news, cars, etc.
  • You will have to modify it as necessary.
  • Have in mind pagination if you have a big collection of records.

As a last step modify the file app.js to add our route:
const sitemapRouter = require("./routes/sitemap");
// (...)
app.use("/sitemap.xml", sitemapRouter);
Run locally
npm start
Open your browser at http://localhost:3000/sitemap.xml
And you will see this output:
<?xml version='1.0'?>
<urlset xmlns='' xmlns:image=''>
            <image:caption> Software development blog. Java, Node JS, Salesforce among other technologies</image:caption>
            <image:caption>Introduction A good practice in software development is to delegate as much heavy work as possible to background jobs</image:caption>
            <image:caption>A small site in Node.js using Express that will have one protected page Http auth basic prompt</image:caption>

After deploying the code in production you’ll want to give visibility to your sitemap.xml. I recommend you submit your URL to the most used (nowadays) search engine: Google.

Go to and submit your URL. Google will inspect it periodically

See the full source code here:

Photo by Annie Spratt on Unsplash
nodejs express sitemap dev