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 = { git = "https://github.com/Proa-Labs/proa.git" }

[build-dependencies]
proa_docs_build = { git = "https://github.com/Proa-Labs/proa.git" }

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. Render it into <head> and every component is styled and wired:

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

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

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 = { git = "https://github.com/Proa-Labs/proa.git" }
```
</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