
# How do I make an XML sitemap?

> A complete recipe for a sitemap page: the Velocity Format, Template, Index Block, Configuration, and Content Type it needs.

URL: https://www.hannonhill.com/cascadecms/latest/articles/developing-in-cascade/seo/make-a-sitemap.html
category: Developing in Cascade
article-type: how-to
content-kind: faq
release-availability: all
tags: templates, blocks, velocity
updated: 2026-10-06

An XML sitemap tells search engines which pages in your site are available to crawl and when each was last modified. There's an example [SEO Sitemap](https://github.com/hannonhill/Velocity-Cookbook/tree/master/Sitemap-SEO) Velocity Format that can be applied to an Index Block configured to index your site.

For the reasoning behind the different approaches, and when each is appropriate, see [Creating a sitemap](https://www.hannonhill.com/cascadecms/latest/articles/developing-in-cascade/strategy/creating-a-sitemap-in-cascade-cms.html). The steps below are one complete working setup.

1.  Create a Velocity [Format](https://www.hannonhill.com/cascadecms/latest/articles/developing-in-cascade/script-formats/index.html) containing the following, replacing `"https://www.example.com"` with your site's URL and `".html"` with your pages' file extension:
    ```velocity
    ## Root domain where website is hosted
    #set ($websiteURL = "https://www.example.com")
    ## Page extension
    #set ($extension = ".html")
    #set ($pages = $_XPathTool.selectNodes($contentRoot, "//system-page[is-published][last-published-on]"))
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
    #foreach ($p in $pages)
       #set ($path = $p.getChild("path").value)
       #set ($last = $p.getChild("last-modified"))
       <url>
          <loc>${websiteURL}${path}${extension}</loc>
          <lastmod>#showDate($last.value, 'yyyy-MM-dd')</lastmod>
       </url>
    #end
    </urlset>
    #macro (showDate $dateValue $formatString)
       #if ($dateValue != "")
           #set ($dateObject = $_DateTool.getDate($dateValue))
       #else
           #set ($dateObject = $_DateTool.getDate())
       #end
       #set ($dateString = $_DateTool.format($formatString, $dateObject))
       ${dateString}
    #end
    ```

1.  Create a [Template](https://www.hannonhill.com/cascadecms/latest/articles/design-in-cascade/templates/index.html) containing a single `DEFAULT` region:
    ```html
    <​system-region name="DEFAULT"/>
    ```

1. Create an [Index Block](https://www.hannonhill.com/cascadecms/latest/articles/content-authoring/blocks/index-blocks.html) with these settings:
    - **Index type** — Folder Index
    - **Index folder** — the base folder of your site
    - **Rendering behavior** — Render normally, starting at the indexed folder
    - **Depth of index** — deep enough to reach the pages in your site
    - **Max rendered assets** — high enough to cover the pages in your site
    - **Indexed asset content** — Regular Content and System Metadata
    - **Indexed asset types** — Pages
    - **Page XML** — Do not render page XML inline
    - **Sort method** — URLs can appear in any order in a sitemap, so choose whatever suits you
1. Create a [Configuration](https://www.hannonhill.com/cascadecms/latest/articles/design-in-cascade/configurations/index.html) and an Output with these settings:
    - **Type of data** — XML
    - **File extension** — .xml
    - **Template** — the Template you created above
    - Check **Publishable**
    - Check **Include XML Declaration in Published Files**
    - In **Regions**, assign the sitemap Index Block and Format to the `DEFAULT` region
1. Create a [Content Type](https://www.hannonhill.com/cascadecms/latest/articles/design-in-cascade/content-types/index.html) using the sitemap Configuration and a Metadata Set of your choice. A Data Definition or WYSIWYG isn't needed.
1. Create a new page in the base folder of your site using that Content Type.

> Index Blocks won't pick up pages that are non-indexable — those with **Include when indexing** unchecked, or whose folder hierarchy prevents indexing. Those pages will be missing from your sitemap.

> You can add further tags such as `changefreq` or `priority` using custom metadata fields on your pages. Make sure the sitemap Index Block also indexes "User Metadata".
