Blog
Generated Routes, Pagination, and Route Metadata
Generated route families keep taxonomies, sitemap pages, and other computed outputs explicit without pushing route bookkeeping into the site program.
Computed routes should still read like ordinary Rust
Static routes are not enough for a real site.
Sooner or later you need outputs such as:
paginated sitemap pages
taxonomy indexes
archive pages
generated JSON indexes
The problem is not whether the engine can produce those routes. The problem is whether the site code stays readable while doing it.
The public API surface
The main API pieces are:
SiteBuilder::generated_routes(...)RouteSourceContextGeneratedRoute<T>GeneratedRoute::file(...)GeneratedRoute::with_source_entry(...)GeneratedRoute::with_attribute(...)paginate(...)RouteInfo
Together, these form the route-family slice of the API.
Generated route families are the escape hatch
generated_routes(...) exists for route sets whose size depends on loaded content.
Its route-source closure runs at build time, after collections load but before route rendering.
That closure receives a RouteSourceContext, which can read collections and return a list of
GeneratedRoute<T> values.
If the closure returns a plain error, the framework reports it as a structured diagnostic tied to
the generated_routes(...) registration site instead of emitting a low-context build failure.
This keeps the site code explicit:
gather the data you want
decide which routes should exist
return the route list directly
There is no hidden DSL inventing route paths for you.
Pagination stays narrow on purpose
The pagination helper does less than many frameworks.
It does not generate paths, templates, or route-side effects. It only splits owned items into numbered pages and returns the data.
That narrowness is deliberate.
The helper removes repetitive bookkeeping, but the route definitions still stay visible at the call site:
paginate(entries, 1000)?
.into_iter()
.map(|page| GeneratedRoute::new(format!("/sitemaps/{}.xml", page.page_number), page))
That is easier to read than a framework-level mini-language.
Route metadata makes joins practical
Generated routes also carry metadata:
with_source_entry(collection, slug)with_attribute(key, value)
Later routes can then inspect ctx.routes() and filter by structured information instead of
guessing from string prefixes.
That is what makes patterns like "sitemap index + several sitemap pages" practical without hard-coding path conventions all over the site.
Why not only collection-backed routes?
collection_page(...) remains the right tool for the common "one route per entry" case.
Generated route families exist for the moment when the route set is a derivation of content rather than a direct mirror of one collection.
That distinction matters because it keeps the simplest API simple while still giving the framework a place for more advanced route families.
Where to go next
Start with Your first site if you want the smaller route API first.
Read Build paginated sitemaps for the concrete task.
Read Generate non-HTML routes when the generated routes are XML, JSON, or flat files.
Read Site-building API for exact API names.