DeCODE logo

How to generate sitemap for NodeJS blog

Extending the Poet functionality

Based on the existing blogging engine, named poet, there was created a fork, and refactored to be for the ES6+ syntax. Also, the project have been completely rewritten with TypeScript. This was done to be compatible with newer libraries and dependencies used in the solution. Also, underscore was replaced with native solutions, so that poet doesn't pull additional dependencies.

To keep poet simple, yet flexible, there was added an additional function, getLinks, which provides links to the tags, posts and categories in the blog.

  getLinks(flatten: boolean) {
    const postCount = this.helpers.getPostCount();
    const posts = this.helpers.getPosts(0, postCount).map((post) => post.url);
    const tags = this.helpers.getTags().map((tag) => `/tag/${tag}`);
    const categories = this.helpers.getCategories().map((category) => `/category/${category}`);
    if(flatten) {
      return [
        ...posts,
        ...tags,
        ...categories
      ]
    }
    return { posts, tags, categories };
  }

Creating a dynamic sitemap for the Express Blog

In your express application, add additional route, which is handling the sitemap generation. You need to set the header, which shows, that the output will be an xml and call a function from poet, which will allow you to retrieve all the links in the blog.

  app.get('/blog-sitemap.xml', (req, res) => {
    res.setHeader('Content-Type', 'application/xml');
    res.render('sitemap', {
      baseUrl: 'https://example.com',
      posts: poet.getLinks(true),
    });
  });

Also, you will need some template, which will be used for the sitemap generation, so you can fill it with something like this:

doctype xml
urlset(xmlns="http://www.sitemaps.org/schemas/sitemap/0.9")
  each post in posts
    - var fullUrl = baseUrl + post
      url
        loc= fullUrl

Changes for the index sitemap

According to Google guide, you can combine multiple sitemaps into a sitemap index. This is a perfect match for the case with auto-generation of sitemap, so you can structure it like so:

<?xml version="1.0" encoding="UTF-8"?>
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <sitemap>
    <loc>https://example.com/blog-sitemap.xml</loc>
  </sitemap>
  <sitemap>
    <loc>https://example.com/another-sitemap.xml</loc>
  </sitemap>
</sitemapindex>

Photo by Andrew Neel on Unsplash