Docs
Quickstart
Build a docs site and start authoring its common components.
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.
[dependencies]
proa_docs = { version = "0.3.0", features = ["axum"] }
[build-dependencies]
proa_docs_build = "0.3.0"
Compile your content in 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.
---
title: Introduction
description: What this site is about.
---
Hello from Proa Docs.
Include the registry and mount a route.
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>:
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:
```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:
<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:
<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:
<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:
<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:
<auto-type-table path="src/config.ts" name="DocsConfig" />
<Demo src="/demos/counter" title="Counter demo" height="320" />
<AgentTerminal />
- Type Table records a request for a TypeScript type and emits a pending placeholder; the build does not resolve it yet. See Type table.
- Demo embeds a same-origin route and requires an accessible title. See Demo.
- Agent Terminal is enabled by
MdxConfig::proa(). See Agent terminal.
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
- File-routed pages, with routes derived from paths under your source root
- A sidebar generated from
meta.json - Syntax highlighting, compiled at build time
- A table of contents per page, from the heading structure
- HTML and Markdown representations of every page, generated from the same source
Next
- Pages and routes: How files become routes, and what frontmatter controls.
- Code block: Highlighting, filenames, line marks, and copy controls.
- Navigation: Order the sidebar with meta.json.