If you want to have a sitemap.xml file for search engines this is something you can very easily create yourself. All you need is a contents file and a custom template.

Contents File

First we need to create a contents file. Since sitemap.xml always goes into the same location we create a folder called sitemap.xml inside our content folder and add a file with the following data:

_template: sitemap.xml
_model: none

This instructs Lektor to use the template sitemap.xml for this page. We also give it the empty none model for good measure.

Starting with Lektor 2.0 you can also add _discoverable: no as a field into the file to hide it from .children. This is useful for such special pages which should be excluded from navigation or automatic link generation.

Template File

The template loaded will be templates/sitemap.xml. In this file we just iterate over all pages of the site recursively. This also automatically skips hidden pages so those will not be generated out.

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="">
  {%- for page in [site.root] if page != this recursive %}
  <url><loc>{{ page|url(external=true) }}</loc></url>
  {{- loop(page.children|sort(attribute='path')) }}
  {%- endfor %}

Sorting the page using |sort(attribute='path') is not mandatory, but can be useful if you prefer to have stable builds, for instance if you use git to version the generated page and would like a clean history or a meaningful diff from the last build.

Note that because sitemaps need to have external URLs (with scheme and everything) you will need to configure the url of the site before the template starts working. For more information see Project File

Human Readable Sitemap

But what if you want a beautiful sitemap as a tree for human reading? This is not any harder. Instead of making a sitemap.xml/ file just create a sitemap/ file instead and use a template like sitemap.html. Then use something like this:

{% extends "layout.html" %}
{% block title %}Sitemap{% endblock %}
{% block body %}
<ul class="sitemap">
  {% for page in [site.root] if page.record_label recursive %}
  <li><a href="{{ page|url }}">{{ page.record_label }}</a>
    {% if page.children %}
      <ul>{{ loop(page.children|sort(attribute='path')) }}</ul>
    {% endif %}
  {% endfor %}
{% endblock %}