Creating a Dynamic Sitemap

Last edit: Jul 09, 2019
  • Contributors:
  • pavelloz
  • diana-lakatos

This guide will help you create a dynamic /sitemap.xml page.


This is an advanced tutorial. To follow it, you should be familiar with basic platformOS concepts, HTML, GraphQL queries, Liquid, topics in the Get Started section and tutorials related to Pages.


Creating a dynamic sitemap.xml is a two-step process:

Step 1: Prepare GraphQL query

Create a GraphQL query which fetches all pages except for the ones that are explicitly excluded via the proper metadata key:

query sitemap_pages($per_page: Int = 1000, $page: Int = 1) {
  pages: admin_pages(
    per_page: $per_page,
    page: $page,
    filter: {
      metadata: {
        has_key: "skip_sitemap"
        exclude: true
  ) {
    results {

Step 2: Setup page

Create views/pages/sitemap.xml.liquid page. Use the GraphQL query defined above to iterate dynamically over all pages.

slug: sitemap
layout_name: ""
  expire: 3600
  skip_sitemap: true

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="">
  {%- graphql g = 'sitemap_pages' -%}
  {% for page in g.pages.results %}
    {% if page.slug == '/' %}{% assign slug = page.slug %}{% else %}{% assign slug = '/' | append: page.slug %}{% endif %}
      <loc>https://{{ }}{{ slug }}</loc>
      <changefreq>{{ page.metadata.sitemap.changefreq | default: 'monthly' }}</changefreq>
      <priority>{{ page.metadata.sitemap.priority | default: 1 }}</priority>
  {% endfor %}

Using this template, you can explicitly exclude any page from the sitemap.xml by including the skip_sitemap key to a metatag property of the page. You can also use metatag to configure any sitemap properties like changefreq and priority. Please note, that the example above already uses static caching for 1 hour - you might want to remove it for development.


We are always happy to help with any questions you may have.