This page covers the implementation-facing side of docs routing.
Use it when you need to answer questions such as:
- which files own docs route resolution
- how stable current routes differ from explicit versioned routes
- how inherited pages become routable
- how version switching and docs search stay version-aware
Runtime Map
Editors usually work in content and nav files. Web developers also need to know which files own version metadata, build-time validation, and runtime route resolution.
Content and Navigation Sources
These files define what the docs tree is supposed to be:
website/data/docs-versions.toml: canonical docs version metadatawebsite/data/docs-nav/<version>.toml: ordered books, sections, and pages
If the docs UI order looks wrong, or a page exists on disk but not in navigation, these are the first files to check.
Build and Tooling Scripts
These scripts keep the docs tree valid and routable:
website/scripts/validate-docs-content.py: validates docs structure, markers, and nav integritywebsite/scripts/materialize-inherited-docs.py: generates transient routable anchors for inherited docs and stable current routeswebsite/scripts/docs-editor.py: CLI for creating, deleting, and renaming docs versions, books, sections, and pages safely
In practice:
- use the validator when you need to confirm content-tree and nav consistency
- use materialization when testing inheritance or stable-current route behavior
- use the docs editor for structural changes instead of hand-editing multiple files
Runtime Template Layer
These files turn the requested docs URL into the page the user actually sees:
website/themes/sambee/layouts/partials/docs/context.html: derives docs path context from the requested routewebsite/themes/sambee/layouts/partials/docs/page-path.html: builds docs content paths with stable-current routing supportwebsite/themes/sambee/layouts/partials/docs/page-url.html: resolves navigable docs URLswebsite/themes/sambee/layouts/partials/docs/source-page.html: resolves the explicit versioned source page behind stable current routeswebsite/themes/sambee/layouts/partials/docs/effective-page.html: resolves the authored page that supplies body content and metadatawebsite/themes/sambee/layouts/partials/docs/render-data.html: prepares shared docs render data, including redirect and indexing statewebsite/themes/sambee/layouts/partials/docs/article-shell.html: renders the shared docs article shellwebsite/themes/sambee/layouts/partials/docs/redirect-target.html: resolves docs entry redirectswebsite/themes/sambee/layouts/partials/docs/nav-tree.html: resolves navigation targets and displayed titleswebsite/themes/sambee/layouts/partials/docs/version-target-url.html: resolves cross-version switch targetswebsite/themes/sambee/layouts/partials/search-modal.html: applies docs-version-aware search behaviorwebsite/themes/sambee/layouts/docs/list.htmlandwebsite/themes/sambee/layouts/docs/single.html: route docs list and page rendering through the shared shell
Theme Assets
These assets shape the visible docs experience once the route and content have been resolved:
website/themes/sambee/assets/css/: shared theme CSS, including docs UI and typography
Requested Route Versus Effective Page
The docs runtime keeps requested-path context separate from effective-content resolution.
Requested Route Context
website/themes/sambee/layouts/partials/docs/context.html derives path context from the requested route and returns values including:
isDocsversionbooksectionpagekindcurrentVersionisExplicitVersionisCurrentRouteisCurrentVersion- convenience booleans:
isDocsRoot,isVersion,isBook,isSection, andisPage
Interpretation rules that matter when changing templates:
- stable current routes such as
/docs/website-dev-guide/...still resolve to the current version even though the version slug is omitted - explicit current-version routes such as
/docs/0.7/...are compatibility routes and should redirect to stable current routes - archived explicit version routes stay routable and render as full docs pages
Effective Content Resolution
website/themes/sambee/layouts/partials/docs/effective-page.html then resolves the authored content source and returns values including:
page: the authored page that should supply title, description, TOC, and body contentrequestedPage: the Hugo page for the requested routerequestedVersion: the version derived from the routeresolvedVersion: the version that supplied the effective contentisInherited: whether the route resolved through inheritance
Templates should render article content and metadata from page, while navigation state, breadcrumbs, and version-switcher state stay tied to the requested route context.
Why Materialization Exists
Hugo needs a concrete page object at the requested path. Raw marker files alone are not enough.
The build therefore materializes transient route anchors under .generated/content/docs so Hugo can route inherited pages and stable current routes without publishing broken /inherit/ or /_inherit/ URLs.
From Hugo’s perspective, inherit.md and _inherit.md are ordinary content files. If the site consumed them directly, Hugo would try to publish the wrong public URLs.
Example:
content/docs/1.1/end-user/getting-started/install/inherit.mdwould naturally publish at/docs/1.1/end-user/getting-started/install/inherit/content/docs/1.1/_inherit.mdwould naturally publish at/docs/1.1/_inherit/
Those are invalid for this docs model. The canonical public URLs must stay attached to the folder path itself:
/docs/1.1/end-user/getting-started/install//docs/1.1/
That creates a routing gap:
- raw marker files must not become public pages
- Hugo still needs a real page or section node at the requested folder path so templates can run and the resolver can supply inherited content
The moving pieces are:
website/hugo.tomlignores raw marker files as direct public pageswebsite/scripts/materialize-inherited-docs.pygenerates transient anchors at the canonical folder pathswebsite/config/_default/module.tomlmounts.generated/contentinto Hugo’s content treewebsite/themes/sambee/layouts/partials/docs/effective-page.htmlresolves the real authored page that should supply the body, title, description, and TOC
During the build, materialize-inherited-docs.py does this work:
- deletes stale generated docs anchors under
website/.generated/content/docs/ - scans
website/content/docs/forinherit.mdand_inherit.md - generates transient
index.mdor_index.mdanchors at the matching canonical folder paths underwebsite/.generated/content/docs/ - generates transient anchors for the declared current version at stable routes under
website/.generated/content/docs/<book>/... - marks inherited-route anchors with
inherit = true - marks stable current-route anchors with
current_route = trueandsource_docs_path = "/docs/<current>/..."
Operational notes:
website/.generated/is build output and is ignored by Git- Hugo mounts
.generated/contentinto the site content tree during the build - Hugo is configured to ignore raw
inherit.mdand_inherit.mdfiles
Without this script, the project would be stuck with two bad options:
- keep raw marker files visible to Hugo and accept broken
/inherit/and/_inherit/URLs - ignore marker files and lose the routable page nodes needed to render inherited docs at canonical folder URLs
Version Switcher Fallback Order
When a reader switches from one docs version to another, the target lookup order is:
- the same page path
- the same section landing path
- the same book landing path
- the target version landing path
Search Behavior
Docs search is intentionally version-aware.
- Pagefind indexes stable current docs URLs, not explicit current-version compatibility routes
- current docs search results therefore keep stable unversioned URLs
- explicit versioned docs pages are excluded from the current-version search index
- on non-docs pages, the UI defaults docs search filters to the
currentversion fromwebsite/data/docs-versions.toml - versions with
searchable = falseare excluded from docs search indexing
Commands for Runtime Changes
The most relevant commands when you are changing docs runtime behavior are:
npm run docs:validate: validate docs content, nav data, markers, and inheritance rules- The validator checks for:
- both
index.mdandinherit.mdin the same page folder - both
_index.mdand_inherit.mdin the same version, book, or section folder - missing required page markers in page folders
- missing required
_index.mdor_inherit.mdin version or book folders - invalid non-empty inheritance marker files
- inheritance chains that never resolve to real content
- nav entries that point to missing version, book, section, or page paths
- duplicate nav slugs in books, sections, or pages
- legacy identity metadata such as
doc_idandproduct_version - disallowed docs front matter such as
aliases
- both
npm run docs:materialize-inherited: regenerate transient inherited-route and stable current-route anchorsnpm run build: generate theme assets, validate docs, materialize docs route anchors, and build the sitenpm run build:search: run the full build and then generate the Pagefind search index