---
search: false
title: Config reference
description: Look up every builder on a proa_docs_build configuration.
---

`proa_docs_build::compile` takes one `Config` value, and every knob in a docs build hangs off it. This page documents that surface: [sources](#docssource) and [schemas](#pageschema), [the Markdown pipeline](#markdownpipeline), [search](#searchconfig), [link validation](#linkvalidation), and [plugins](#plugins).

## Config

`Config` is the top-level build object that you pass to `proa_docs_build::compile(config)`.

```rust filename="build.rs"
let config = proa_docs_build::Config::new()
    .source(docs_source)
    .source(blog_source)
    .plugin(proa_docs_build::plugins::last_modified());
```

| Method | Purpose |
|--------|---------|
| `Config::new()` | Create an empty config. |
| `.source(DocsSource)` | Add a docs-like source that emits a `Docs` registry. |
| `.collection(CollectionSource)` | Add a collection source for future non-doc data pipelines. |
| `.plugin(Plugin)` | Add build plugins. |
| `.sources()` | Read configured docs sources. |
| `.collections()` | Read configured collection sources. |
| `.plugins()` | Read configured plugins. |

Sources do the compiling, and `DocsSource` is the one that produces docs pages.

## DocsSource

`DocsSource::new(root)` compiles one documentation tree.

| Setting | Default | Builder |
|---------|---------|---------|
| `root` | required | `DocsSource::new(root)` |
| `out_dir_name` | `docs` | `.out_dir_name("docs")` |
| `base_path` | `/docs` | `.base_path("/docs")` |
| `site_name` | `Docs` | `.site_name("Proa Docs")` |
| `schema` | empty | `.schema(PageSchema::new())` |
| `meta_schema` | empty | `.meta_schema(MetaSchema::new())` |
| `postprocess` | enabled defaults | `.postprocess(Postprocess::new())` |
| `markdown` | default pipeline | `.markdown(MarkdownPipeline::default())` |
| `search` | `SearchConfig::orama_client()` | `.search(SearchConfig::disabled())` |
| `link_validation` | warn, internal links on | `.link_validation(LinkValidation::strict())` |
| `include_drafts` | `false` | `.include_drafts(true)` |

The compiler normalizes `base_path`. Empty input and `/` become `/`; all other values get a leading slash and no trailing slash.

Two of those settings, `schema` and `meta_schema`, describe the metadata a tree must carry.

## PageSchema

`PageSchema` validates frontmatter fields that your collection requires:

```rust filename="build.rs"
let schema = proa_docs_build::PageSchema::new()
    .required_string("title")
    .optional_string("description")
    .bool_with_default("draft", false)
    .date("last_modified");
```

| Method | Check |
|--------|-------|
| `.required_string(name)` | Field must exist and be a string. |
| `.optional_string(name)` | Field may exist and must be a string. |
| `.bool_with_default(name, default)` | Field may exist and must be a boolean. |
| `.date(name)` | Field may exist and must parse as a date-like string. |

Schema validation checks the fields you configure. The compiler allows unknown fields, so app-specific frontmatter passes through.

Directory metadata lives in `meta.json` files, and `MetaSchema` checks those.

## MetaSchema

`MetaSchema` supports optional string validation:

```rust filename="build.rs"
let meta_schema = proa_docs_build::MetaSchema::new()
    .optional_string("title")
    .optional_string("icon");
```

Use it when a site wants typed checks for custom `meta.json` metadata.

Past validation, `Postprocess` decides which side artifacts the build keeps.

## Postprocess

`Postprocess` controls generated side artifacts.

| Method | Default | Effect |
|--------|---------|--------|
| `.include_processed_markdown(bool)` | `true` | Keep Markdown source copies for static `.md` routes. |
| `.extract_link_references(bool)` | `true` | Record links for validation. |
| `.export_element_ids(bool)` | `true` | Export heading IDs for hash validation and TOC data. |

The largest artifact, page HTML, comes out of the Markdown pipeline.

## MarkdownPipeline

`MarkdownPipeline` controls the Markdown compiler:

```rust filename="build.rs"
let markdown = proa_docs_build::MarkdownPipeline::default()
    .code_highlighting(proa_docs_build::CodeHighlight::new())
    .mdx(proa_docs_build::MdxConfig::proa())
    .mermaid(proa_docs_build::MermaidConfig::new())
    .math(proa_docs_build::MathMode::Katex)
    .component_indexing(
        proa_docs_build::ComponentIndexing::new()
            .preserve(["Cards", "Files"])
            .children_only_default(true),
    )
    .typescript(proa_docs_build::TypeScriptDocgen::new().command("pnpm docgen"));
```

| Builder | Purpose |
|---------|---------|
| `.code_highlighting(CodeHighlight)` | Highlight recognized code fences with Syntect during the docs build. |
| `.math(MathMode)` | Configure math handling. |
| `.component_indexing(ComponentIndexing)` | Preserve or index component-shaped inline HTML. |
| `.mdx(MdxConfig)` | Configure deterministic MDX-to-Markdown lowering. |
| `.mermaid(MermaidConfig)` | Turn Mermaid fences into diagram placeholders. |
| `.typescript(TypeScriptDocgen)` | Configure TypeScript type-table extraction. |

Each builder gets its own section below, starting with `CodeHighlight`.

## CodeHighlight

| Constructor | Behavior |
|-------------|----------|
| `CodeHighlight::new()` | Enable highlighting. |
| `CodeHighlight::disabled()` | Disable highlighting. |
| `.enabled(bool)` | Toggle explicitly. |

With highlighting on, Syntect maps recognized-language tokens to stable semantic
`hl-*` classes during the docs build. The site supplies the class colors,
including light and dark themes. Unknown languages fall back to escaped
`<pre><code>`; the bundled syntax set currently excludes TypeScript, TSX, and
TOML. Every highlight-enabled block carries `data-code-highlight="syntect"`,
safe fallback blocks included, so client-side highlighters can skip them.

`MathMode` handles the other class of typeset content.

## MathMode

| Mode | Behavior today |
|------|----------------|
| `MathMode::Disabled` | Default. The compiler escapes math events as text. |
| `MathMode::Katex` | Configuration surface exists; your app can layer in KaTeX rendering. |

MDX lowering, unlike math handling, rewrites the source before the parser sees it.

## MdxConfig

`MdxConfig` is an optional build-time lowering pass for `.mdx` files. It does not execute arbitrary MDX or JavaScript. It rewrites a small configured helper subset to plain Markdown before the normal Markdown compiler runs.

```rust filename="build.rs"
let markdown = proa_docs_build::MarkdownPipeline::default()
    .mdx(proa_docs_build::MdxConfig::proa());
```

| Constructor | Behavior |
|-------------|----------|
| `MdxConfig::disabled()` | Default. The pipeline does not lower `.mdx` files. |
| `MdxConfig::new()` | Enable the lowerer: it normalizes syntax, strips imports, and rejects exports. Helpers stay off until you select them. |
| `MdxConfig::proa()` | Preset used by this site: Cards, Files, AgentTerminal, simple images, simple paragraph tags, layout div removal, class/style normalization, and fence metadata normalization. |

| Builder | Purpose |
|---------|---------|
| `.enabled(bool)` | Toggle the MDX lowering pass. |
| `.strip_imports(bool)` | Remove `import ... from ...` lines. |
| `.reject_exports(bool)` | Fail on `export ...` lines. |
| `.normalize_brace_escapes(bool)` | Convert authored `{ / }` escape helpers back to literal braces. |
| `.normalize_fence_metadata(bool)` | Strip unsupported fence metadata such as `title="main.rs"`; preserve the language, `filename="..."`, and `{2,4-5}` selected-line ranges. |
| `.normalize_class_name(bool)` | Convert `class=` to `class=`. |
| `.normalize_style_objects(bool)` | Convert simple `style=""` objects to string style attributes. |
| `.remove_layout_divs(bool)` | Drop layout-only `<div>` wrappers. |
| `.lower_paragraph_tags(bool)` | Convert simple `<p>`, `<strong>`, and `<code>` HTML to Markdown text. |
| `.cards(bool)` | Lower `<Cards>` with `<Card />` children to Markdown bullet links. |
| `.files(bool)` | Lower `<Files>` with `<Folder>` and `<File>` children to a `proa-filetree` fence. |
| `.agent_terminal(bool)` | Lower `<AgentTerminal />` to a static `text` code fence. |
| `.images(MdxImageConfig)` | Configure simple `<img ... />` lowering. |

The pass writes its processed Markdown into `DocPage::markdown`, which the `.md` routes serve.

Images take enough options to warrant their own config.

## MdxImageConfig

`MdxImageConfig` controls simple image lowering:

```rust filename="build.rs"
let images = proa_docs_build::MdxImageConfig::new()
    .default_alt("Image")
    .rewrite_prefix("/images/", "/static/images/");
```

| Constructor / Builder | Purpose |
|-----------------------|---------|
| `MdxImageConfig::new()` | Enable image lowering. |
| `MdxImageConfig::disabled()` | Disable image lowering. |
| `.enabled(bool)` | Toggle image lowering. |
| `.default_alt(value)` | Alt text used when an authored image omits `alt`. |
| `.rewrite_prefix(from, to)` | Rewrite a source path prefix before emitting Markdown image syntax. |

Diagrams survive lowering as `mermaid` fences, which `MermaidConfig` picks up.

## MermaidConfig

`MermaidConfig::new()` enables Mermaid support.

| Setting | Default | Builder |
|---------|---------|---------|
| `enabled` | `false`, `true` from `new()` | `MermaidConfig::new()` |
| `code_fences` | `true` | `.code_fences(false)` |
| `renderer` | `MermaidRenderer::Client` | `.renderer(...)` |
| `fallback` | `MermaidFallback::CodeBlock` | `.fallback(...)` |

The renderer accepts `Client`, `StaticSvg`, and `Custom`. The current compiler emits client-rendered placeholders for Mermaid fences when you enable them.

Components the lowerer leaves alone can still reach an app-level pass through `ComponentIndexing`.

## ComponentIndexing

| Method | Purpose |
|--------|---------|
| `ComponentIndexing::new()` | Create default config. |
| `.preserve(names)` | Preserve named component directives for app-level processing. |
| `.children_only_default(bool)` | Treat unconfigured components as children-only by default. |

Use this when an app runs an additional external MDX lowering pass and wants component-shaped inline HTML preserved for that pass.

TypeScript docgen is one such external pass.

## TypeScriptDocgen

`TypeScriptDocgen::new()` enables type-table requests. The default component name is `auto-type-table`.

| Method | Purpose |
|--------|---------|
| `.enabled(bool)` | Toggle TypeScript docgen. |
| `.tsconfig_path(path)` | Select the TypeScript config. |
| `.base_path(path)` | Select the path base used by docgen. |
| `.cache_dir(path)` | Select the cache directory. |
| `.component_name(name)` | Change the directive component name. |
| `.hide_internal(bool)` | Hide internal API items. |
| `.annotation(Annotation)` | Add a JSDoc annotation mapping. |
| `.command(command)` | Configure the external docgen command. |

Compilation fails when Markdown requests type tables and you enable TypeScript docgen **without** a command. That avoids silently publishing unresolved type API placeholders.

With the pages compiled, `SearchConfig` decides how readers find them.

## SearchConfig

| Mode | Constructor |
|------|-------------|
| Disabled | `SearchConfig::disabled()` |
| Orama client | `SearchConfig::orama_client()` |
| Static client | `SearchConfig::static_client()` |
| Server-owned search | `SearchConfig::Server` |
| Custom integration | `SearchConfig::Custom(String)` |

Every enabled mode emits a search manifest and documents JSON today. Your app decides whether to load them on the client, serve them through an API, or feed another index.

`LinkValidation` guards the other half of navigation: the links themselves.

## LinkValidation

`LinkValidation::default()` warns on broken internal links and hashes. `LinkValidation::strict()` turns those warnings into build errors.

| Method | Purpose |
|--------|---------|
| `.mode(LinkValidationMode)` | `Off`, `Warn`, or `Error`. |
| `.check_internal(bool)` | Check absolute and relative internal route targets. |
| `.check_hashes(bool)` | Check heading hashes. |
| `.check_relative_paths(RelativePathMode)` | Ignore, URL-resolve, or file-resolve relative links. |
| `.check_external(ExternalLinkCheck)` | Configure external link checking. |
| `.component_attr(component, attr)` | Register component attributes that contain links. |
| `.static_root(path)` | Register static asset roots. |

See [Link validation](/docs/proa-docs/link-validation) for examples.

Collections reuse the same source shape for data that is not a docs page.

## CollectionSource

`CollectionSource` is available for future collection compilation.

| Method | Purpose |
|--------|---------|
| `CollectionSource::new(root)` | Create a collection source. |
| `.kind(CollectionKind)` | Select `Doc` or `Data`. |
| `.schema(PageSchema)` | Validate collection frontmatter. |
| `.root()` | Read the source root. |
| `.collection_kind()` | Read the configured kind. |

Plugins are the last extension point on `Config`.

## Plugins

`proa_docs_build` exposes two plugin constructors today:

| Plugin | Purpose |
|--------|---------|
| `plugins::json_schema()` | Reserve schema output integration. |
| `plugins::last_modified()` | Reserve last-modified metadata integration. |

The plugin API stays small while docs compilation stabilizes.

## Next steps

- [Configuration](/docs/proa-docs/configuration)
  - Wire these builders into a production `build.rs`.
- [Markdown pipeline](/docs/proa-docs/_retired/markdown-pipeline)
  - Follow a page through MDX lowering, fences, Mermaid, and search text.
- [Link validation](/docs/proa-docs/link-validation)
  - Fail the build on broken internal routes and heading hashes.
- [Runtime](/docs/proa-docs/runtime)
  - Include the generated registry and render it from your app.
