Skip to content
🗺 Build a dynamic sitemap.xml file based on content pulled in from Contentful via the Contentful API.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.

🗺 contentful-sitemap

npm version npm Coverage Status CircleCI Greenkeeper badge

Build a dynamic sitemap.xml file based on content pulled in from Contentful via the Contentful API.


Via npm

npm install contentful-sitemap

Via Yarn

yarn add contentful-sitemap

How to use

contentful-sitemap requires a Contentful client in order to fetch entries from your Contenful space in order to build your dynamic sitemap entries. So, make sure you have contentful as a dependency in your project.

Install contentful

npm i -S contentful

Create Contentful client

const contentful = require('contentful');
const ContentfulSitemap = require('contentful-sitemap');

const client = contentful.createClient({
  accessToken: '[ACCESS_TOKEN]',
  space: '[SPACE_ID]',

Next comes setting up the ContentfulSitemap instance that will be used by your /sitemap.xml route to generate and return the sitemap. ContentfulSitemap requires a client instance, so make sure you pass one into the constructor.

Create ContentfulSitemap instance

const sitemap = new ContentfulSitemap([], client, {options});


  • routes - Array of route definitions to use to generate sitemap.

  • client - Contentful client that will be used for fetching locales and entries from Contentful.

  • options - Options that you can use to customize how sitemaps are generated.


contentful-sitemap uses the sitemap package behind the scenes to generate the final XML that is returned, so all route options supported by that package are also supported. Below are the few specifics that directly relate to how contentful-sitemap will process your routes entries.

Name Default Description
url null Use this property if the path you are providing does not require any segments to be swapped out dynamically.
id null Contentful entry id to fetch for the specific path. Only used if the dynamicLastmod option is set to true.
pattern null path-to-regexp pattern to use for generating dynamic listings based on Contentful content or setting locale specific paths.
priority 1 Default priority to set for each url. Set to 1 as a default so it can be excluded in your routes definitions.
params null Object used to specify the mapping of pattern parameter to Contentful response data.
query null Query used by the Contentful client for fetching entries. All contentful getEntries query options are supported.

Default Options

The following options can be used to customize the way your sitemap is generated. The one option that you’ll definitely want to set, if not defined in your routes is the origin option, which is prefixed before the urls and patterns defined in your routes.

Name Default Description
locales [] Array of locales to include for all route instances, if not using dynamicLocales.
dynamicLocales false Whether or not to fetch the list of enabled locales from Contentful.
dynamicLastmod false Automatically use the sys.updatedAt value of each entry to set the lastmod value.
origin '' The origin to prefix each url or pattern with.
localeParam locale The param to set within your pattern to replace with a locale.
defaultLocale null The default locale that will be used in the main loc value for a url.


  • addRoute(route) - Method to use for adding additional urls after the initial ContentfulSitemap instance has been created.

  • toXML((xml, err) => {}) - The magic Call this method when you want to generate your sitemap.


const express = require('express');
const contentful = require('contentful');
const ContentfulSitemap = require('contentful-sitemap');

const app = express();

const client = contentful.createClient({
  accessToken: '[ACCESS_TOKEN]',
  space: '[SPACE_ID]',

const sitemap = new ContentfulSitemap([
    pattern: '/',
    id: '[HOME_PAGE_ID]',
    pattern: '/about',
    id: '[ABOUT_PAGE_ID]',
    priority: 0.7,
    pattern: '/news',
    id: '[NEWS_PAGE_ID]',
    pattern: '/news/:slug',
    priority: 0.5,
    query: {
      select: 'fields.slug',
    params: {
      slug: 'fields.slug',
    url: '/terms',
    priority: 0.3,
    url: '/privacy',
    priority: 0.3,
], client);

app.get('/sitemap.xml', (req, res) => {
  sitemap.toXML((xml, err) => {
    if (err) {
      return res.status(500).end();

    res.header('Content-Type', 'application/xml');



MIT © Ryan Hefner

You can’t perform that action at this time.