Docs

Customizing the layout

Compose the render primitives instead of using the default shell.

Open Markdown

DocsShell renders a complete docs page: sidebar, article, table of contents, pager. It emits the whole document, <head> included. Most sites never need more.

src/pages/docs.rs
use proa_docs::DocsShell;

DocsShell { docs, page }.render(cx)?;

DocsShell writes its own <head> (charset, viewport, title, description) and has no slot for a stylesheet link, so the default theme only applies when you compose your own head and render DocsAssets there, as shown in Styling. DEFAULT_STYLESHEET and DEFAULT_SCRIPT are the bytes to serve for it.

When you want your own chrome, compose the pieces yourself.

The primitives

ComponentRenders
DocsShellThe whole page. Start here
DocsNavThe sidebar tree for a path
DocsNavItemOne nav entry, if you are building the tree yourself
DocsSectionMenuThe section switcher, when any folder is a root
DocsTocOn-this-page headings
DocsPagerPrevious and next links
TypeTableAn API table from rows your app supplies; the build does not produce them
nav_icon_svgAn icon by name, for your own chrome

Apart from TypeTable, each takes data from the compiled Docs registry, so they stay in sync with content without threading state.

Replacing one piece

Keep the primitives, wrap them in your own markup. This is what the Proa site does — its sidebar adds a logo, a search trigger, and a theme toggle around the same DocsNav you would use:

src/components/docs/sidebar.rs
use proa_docs::{DocsNav, DocsSectionMenu};

html_sync! {
    <div class="docs-sidebar-inner">
        <div class="docs-sidebar-header">
            {SearchTrigger { class: Some("docs-sidebar-search") }}
            {DocsSectionMenu { docs, active_path: page.route_path }}
        </div>
        <div class="docs-sidebar-content">
            {DocsNav {
                items: docs.nav_items_for_path(page.route_path),
                active_path: page.route_path,
            }}
        </div>
    </div>
}

proa_marketing/src/components/docs/ in the Proa repository is the full worked example — sidebar, article, and page, each wrapping primitives rather than replacing them.

Reading the registry directly

For chrome the primitives do not cover, walk the model:

TypeHolds
DocsConfig, every page, the nav tree, search artifacts
DocPageSlug, route, title, description, article HTML, TOC, prev/next
NavItemOne nav node: page, group, separator, or root
TocItemDepth, id, title
src/pages/docs.rs
let page = docs.page_for_path(path)?;
let items = docs.nav_items_for_path(page.route_path);

nav_items_for_path returns a root section's children when the path is inside one, and the whole tree otherwise. That single call is what makes the section switcher work.

Styling what you build

The primitives emit stable class and data- hooks, all documented in Styling contract. Your own wrapper markup is yours to style; the parts you compose keep working with the default theme.

Rendering pages · Styling contract · Navigation

Search

Type at least 2 characters