Sitemaps & Feeds


The livingdocs-server ships with a set of APIs to automatically create sitemaps. The full Public API specification can be found in our Public API documentation.

This guide will focus on the setup of Sitemaps within a delivery and the downstream customizations that need to be done to set up Feeds.

We provide a running minimal delivery, in the “Live Delivery Setup” section


You will need to link the Sitemap and Feed in the robots.txt of your delivery


Sitemap index

The Sitemap index points to individual months, that contain all the actual entries of a Sitemap. Several Sitemaps for various content types could be created if they are individually linked in the robots.txt file.

Sitemap entries

The Sitemap entries follow the schema sitemap.YYYY-MM.xml or if it has more than the suggested limit of entries it will be split into a separate file such as sitemap.YYYY-MM.2.xml. We suggest keeping the limits the Livingdocs API provides.


Feeds are highly customizable and no there is no ‘one-fits-it-all’ solution. We will still outline a way to integrate Feeds using one of our helper methods for Feeds that builds upon the RSS 2.0 Specification

Server Downstream You will need to add your own HTTP-API.

// /app/server.js
liServer.registerInitializedHook(function () {
  const searchManager = server.features.api('li-search').searchManager
  const sitemapsApi = server.features.api('li-sitemaps')

  const feedsApi = require('./feeds_api')({

    title: 'RSS Feeds',
    description: 'Feed endpoints',
    method: 'get',
    prefix: '/daily-planet',
    path: '/feed',
    auth: 'public-api:read',

    async action (req, res) {
      const {channelId, projectId} = req.verifiedToken
      const feed = await feedsApi.getFeed({channelId, projectId})
      return res.success(feed)
// Setup the Feature - ./feeds/feeds_api.js
module.exports = ({searchManager, sitemapsApi}) => {
  return {
    async getFeed ({projectId, channelId}) {
      // gather the latest published documents with the 'article' contentType
      const res = await searchManager.searchPublications({
        projectId: projectId,
        channelId: channelId,
        contentTypes: ['article']
      // render the XML
      const xml = sitemapsApi.renderFeedXml({
        title: 'Feed title',
        description: 'Feed description',
        language: 'de',
        copyright: 'Feed copyright',
        link: '',
        pubDate: res.results[0]?.createdAt,
        lastBuildDate: new Date(),
        image: {
          url: '',
          title: 'image title',
          description: 'image description',
          link: '',
          width: '144',
          height: '400'
        items: => {
          return {
            title: 'document title',
            description: 'document description',
            pubDate: doc.createdAt,
            link: `${doc.documentId}`
      return xml

Result Note: This still result still needs to be consumed in the delivery, similar to the already implemented examples in the live delivery example in the next section.

<!-- example payload of the new downstream Feeds endpoint -->
<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <title>Feed title</title>
  <description>Alle Artikel von Livingdocs</description>
    <description>some description for this image</description>
  <pubDate>Wed, 19 May 2021 14:55:06 GMT</pubDate>
  <lastBuildDate>Wed, 19 May 2021 14:55:06 GMT</lastBuildDate>
    <title>foo item title</title>
    <description>foo item description</description>
    <pubDate>Tue, 01 Jan 2030 00:00:00 GMT</pubDate>

Live Delivery Setup

This live demo of a minimal delivery runs against a real Livingdocs instance.

You can explore the following routes in the example

  • /robots.txt
  • /sitemap.xml
  • /sitemap.2021-06.xml
  • /feed.xml

Interactive minimal delivery example