Solve one concrete task
Build paginated sitemaps
Use generated route families and the pagination helper to emit a sitemap index plus many sitemap pages.
Build a sitemap index and several sitemap pages
Use generated_routes(...) when the number of sitemap pages depends on the amount of content. Use paginate(...) to keep the page-number bookkeeping out of your route code while leaving the route paths explicit.
Generate the sitemap pages
The route-source closure reads collections, builds a list of entries, paginates it, and returns one GeneratedRoute per sitemap page:
.generated_routes(
|routes| {
let mut entries = Vec::new();
for entry in routes.collection::<BlogPost>("blog")? {
entries.push(SitemapEntry {
path: format!("/blog/{}/", entry.slug),
title: entry.frontmatter.title.clone(),
});
}
entries.sort_by(|left, right| left.path.cmp(&right.path));
Ok(site_core::paginate(entries, 1000)?
.into_iter()
.map(|page| {
GeneratedRoute::new(
format!("/sitemaps/{}.xml", page.page_number),
SitemapPage { entries: page.items },
)
.with_attribute("family", "sitemap")
.with_attribute("page", page.page_number.to_string())
})
.collect::<Vec<_>>())
},
|_ctx, page| Ok(Artifact::Xml(build_sitemap_page_xml(&page.entries))),
)
The important part is that the helper does not invent route paths for you. It only returns numbered chunks.
Generate the sitemap index
The index is an ordinary route that inspects the route manifest:
.page("/sitemap.xml", |ctx| {
let mut sitemap_paths = ctx
.routes()
.iter()
.filter(|route| route.has_attribute("family", "sitemap"))
.map(|route| route.path.as_str())
.collect::<Vec<_>>();
sitemap_paths.sort_unstable();
let mut xml = String::from(r#"<?xml version="1.0" encoding="UTF-8"?><sitemapindex>"#);
for path in sitemap_paths {
xml.push_str("<sitemap><loc>");
xml.push_str(path);
xml.push_str("</loc></sitemap>");
}
xml.push_str("</sitemapindex>");
Ok(Artifact::Xml(xml))
})
This works because route generation is a build phase with visible outputs, not an opaque side effect.
Add route metadata when you need it
Use generated-route metadata for the joins you know you need later:
with_attribute(...)to label a route family such assitemapwith_source_entry(...)when a later route needs to connect back to a specific content entry
That is more robust than trying to infer behavior from path prefixes alone.