Docs

Quickstart

Build a docs site and start authoring its common components.

Open Markdown

Two crates, a build script, and one route.

Starting from scratch?

proa new site my-docs --template docs --yes scaffolds a site with this wiring already in place, and proa new site my-app --template origin --yes scaffolds ORIGIN, the full reference application, if you want to study a complete Proa app (data loading, islands, streamed sections, and Markdown representations) while you write your docs. The steps below wire proa_docs into an existing site by hand.

Add the dependencies.

Cargo.toml
[dependencies]
proa_docs = { version = "0.3.0", features = ["axum"] }

[build-dependencies]
proa_docs_build = "0.3.0"

Compile your content in build.rs.

build.rs
use proa_docs_build::{
    CodeHighlight, Config, DocsSource, MarkdownPipeline, MdxConfig,
};

fn main() {
    let markdown = MarkdownPipeline::default()
        .code_highlighting(CodeHighlight::new())
        .mdx(MdxConfig::proa());

    let docs = DocsSource::new("src/docs")
        .out_dir_name("docs")
        .base_path("/docs")
        .site_name("My Docs")
        .markdown(markdown);

    proa_docs_build::compile(Config::new().source(docs));
}

Write a page.

src/docs/index.mdx
---
title: Introduction
description: What this site is about.
---

Hello from Proa Docs.

Include the registry and mount a route.

src/pages/docs.rs
use axum::{extract::Path, response::IntoResponse, routing::get, Router};
use proa_docs::{include_docs, Docs};

pub fn docs() -> &'static Docs {
    static DOCS: Docs = include_docs!("docs");
    &DOCS
}

async fn docs_page(Path(path): Path<String>) -> impl IntoResponse {
    let path = format!("/docs/{path}");
    proa_docs::adapter::axum::response(docs(), &path)
}

pub fn router() -> Router {
    Router::new()
        .route("/docs", get(|| async { docs_page(Path(String::new())).await }))
        .route("/docs/*path", get(docs_page))
}

The adapter needs the axum feature on proa_docs. Runtime shows the same handler written by hand.

Run it and open /docs.

Styling

proa_docs ships a default theme. In a custom document shell, render its assets inside <head>:

src/layouts/root.rs
use proa_docs::DocsAssets;

html_sync! {
    <head>{DocsAssets::new()}</head>
}

The default DocsShell used by the adapter above owns its head and has no asset slot. To install these assets, compose your own document from the primitives in Customizing the layout; adding a second <head> around DocsShell would produce an invalid document.

On a site with many pages, serve DEFAULT_STYLESHEET and DEFAULT_SCRIPT as static files instead so they cache between navigations.

Theming is 15 CSS custom properties — see Styling contract.

Add components in MDX

Components are authored directly in an .mdx page. There are no Rust imports and no runtime registration step. The MdxConfig::proa() preset in the build script above also enables the three opt-in helpers: Cards, Files, and Agent Terminal.

Code blocks and callouts

Fenced code is highlighted during the build. Add filename for a header and {...} to mark lines. Use a Callout to separate a note or warning from the surrounding prose:

src/docs/deploy.mdx
```rust filename="src/main.rs" {2}
fn main() {
    println!("ready");
}
```

<Callout type="warning">
Deploy only after the health check passes.
</Callout>

See Code block and Callout for their complete options.

Cards

Cards turn a list of destinations into a consistent link list, one entry per card:

src/docs/index.mdx
<Cards>
  <Card title="Quickstart" description="Set up the site." href="/docs/quickstart" />
  <Card title="Deploy" description="Ship the site." href="/docs/deploy" />
</Cards>

Each Card is self-closing and requires title and href. See Cards.

Tabs, steps, and accordions

Use Tabs for alternatives, Steps for ordered work, and Accordions for optional detail:

src/docs/install.mdx
<Tabs data-items="Cargo|cargo-binstall">
<Tab value="Cargo">
Run `cargo install proa-cli`.
</Tab>
<Tab value="cargo-binstall">
Run `cargo binstall proa-cli`.
</Tab>
</Tabs>

<Steps>
<Step>
Create the docs source directory.
</Step>
<Step>
Mount the generated registry.
</Step>
</Steps>

<Accordions>
<Accordion title="Does this need JavaScript?">
No. The disclosure behavior is CSS-only.
</Accordion>
</Accordions>

Read the full Tabs, Steps, and Accordions guides for attributes and constraints.

Multi-file examples

Code Explorer keeps related files together without stacking every listing down the page:

src/docs/setup.mdx
<CodeExplorer>
<CodeFile name="Cargo.toml">
```toml
[build-dependencies]
proa_docs_build = "0.3.0"
```
</CodeFile>
<CodeFile name="build.rs">
```rust
fn main() {
    proa_docs_build::compile(config);
}
```
</CodeFile>
</CodeExplorer>

Each Code File requires a unique name, and one explorer supports up to eight files. See Code explorer.

File trees

Use Files when the directory structure itself is part of the explanation:

src/docs/structure.mdx
<Files>
<Folder name="src">
<Folder name="pages">
<File name="docs.rs" />
</Folder>
<File name="main.rs" />
</Folder>
<File name="build.rs" />
</Files>

See Files. For a quick text-only tree, use a proa-filetree code fence instead.

Generated references, demos, and terminal output

These components are self-closing:

src/docs/reference.mdx
<auto-type-table path="src/config.ts" name="DocsConfig" />

<Demo src="/demos/counter" title="Counter demo" height="320" />

<AgentTerminal />

Math and diagrams

Math and Mermaid are Markdown-pipeline features rather than MDX tags. Enable Math with .math(MathMode::MathMl) and write dollar-delimited TeX. Mermaid uses a mermaid code fence and needs a renderer supplied by your application.

See Math and Mermaid for their build configuration.

What you get without doing anything else

Next

Search

Type at least 2 characters