Sitemap navigator
Populating the sitemap navigator allows you to use it for navigating website pages. The sitemap navigator provides a single point from which to access all editable pages on a website.
Navigate the sitemap
Section titled “Navigate the sitemap”The sitemap provides two ways to navigate:
Tree view
Section titled “Tree view”The sitemap is built in a hierarchical way using the urlPath
from page documents. (More on this below.)
It is collapsed by default, so that only top-level pages are visible. Each page can be expanded and collapsed as needed.
Search pages
Section titled “Search pages”On larger sites, it’s usually easier to search for a page. The search field is automatically focused when opening the sitemap. Search values query a page document’s title
and urlPath
properties.
Populate the sitemap
Section titled “Populate the sitemap”The sitemap will be populated by default, according to your content schema. If the slug of the page is not part of the content schema, you need to override the default sitemap behavior.
Default sitemap from pages
Section titled “Default sitemap from pages”By default, the sitemap is populated by retrieving the urlPath
value from all documents of models with the type
property set to page
.
If your content source uses inferred schemas (most headless CMSs) or does not have the concept of pages, you need to extend the models that represent pages.
Make sure the name
of the page model object corresponds to the name in the json schema that appears in the headless CMS.
// stackbit.config.tsimport { defineStackbitConfig } from "@stackbit/types";
export default defineStackbitConfig({ contentSources: [ // ... ], modelExtensions: [ { name: "page", type: "page", urlPath: "/{slug}" }, { name: "post", type: "page", urlPath: "/blog/{slug}" } ]});
In this case, all pages and posts will show up in the sitemap.
Custom sitemap
Section titled “Custom sitemap”To override default behavior, use the siteMap
property.
The siteMap
property provides an array of SiteMapEntry
objects. These objects can specify URL paths or be tied directly to a document. We suggest using TypeScript to introspect the expected properties.
Here’s an example that implements a similar approach to the default sitemap behavior. To ensure stableId
is set to a value that will not change, the example includes logic to set a unique pageId
for each page, if one doesn’t exist already. The pageId
is then used for the stableId
when generating the siteMap
.
// stackbit.config.tsimport { defineStackbitConfig, getLocalizedFieldForLocale, SiteMapEntry} from "@stackbit/types";
export default defineStackbitConfig({ stackbitVersion: "~0.6.0", contentSources: [ // ... ], // 1: add the `pageId` field here modelExtensions: [ { name: "page", type: "page", urlPath: "/{slug}", fields: [{ name: "pageId", type: "string", hidden: true }] } ],
// 2: add this method to create the ID when creating a page async onContentCreate({ object, model }) { if (model.type !== "page") { return object; } // for pages that already have a pageId field, use that value; if not, generate one const hasPageIdField = !!model.fields?.find( field => field.name === "pageId" ); if (hasPageIdField && !object.pageId) { object.pageId = Date.now().toString(); }
return object; },
siteMap: ({ documents, models }) => { const pageModels = models.filter(m => m.type === "page").map(m => m.name); return documents .filter(d => pageModels.includes(d.modelName)) .map(document => { // 3: use the pageId value for the stableId const slugField = document.fields.slug.type === "slug" ? document.fields.slug : undefined; const pageIdField = document.fields.pageId.type === "string" ? document.fields.pageId : undefined;
const slug = getLocalizedFieldForLocale(slugField); const pageId = getLocalizedFieldForLocale(pageIdField);
if (!slug.value || !pageId.value) return null;
const urlPath = "/" + slug.value.replace(/^\/+/, "");
return { stableId: pageId.value, urlPath, document, isHomePage: urlPath === "/" }; }) .filter(Boolean) as SiteMapEntry[]; }});
Did you find this doc useful?
Your feedback helps us improve our docs.