---
title: Components
description: MDX components the pipeline knows how to flatten into agent-readable markdown.
group: authoring
lastModified: '2026-05-11T20:02:32-07:00'
lastAuthor: 'github-actions[bot]'
---
# Components

Leadtype does not ship UI components. **Your docs app owns runtime rendering, styling, and accessibility** — it only has to honor a small naming contract so the remark pipeline can flatten each component into markdown for agents, search, and `llms-full.txt`.

## Why flatten at all?

Interactive MDX components like `<Tabs>` or `<Callout>` render fine in a browser but do nothing for an agent reading raw text. *Flattening* converts each component into a portable markdown equivalent at conversion time:

* A `<Callout>` becomes a blockquote.
* A `<Tabs>` becomes a stack of bold headings, one per tab.
* A `<TypeTable>` becomes a markdown table.
* A `<Mermaid>` becomes a fenced ` ```mermaid ` block — the diagram source survives so other tooling can render it.

This means the same content reaches three audiences (humans, agents, search) without you maintaining two copies.

## The naming contract

The remark pipeline recognizes these names. If your components use the same names, flattening Just Works:

`Accordion`, `AccordionItem`, `Audience`, `Callout`, `Card`, `Cards`, `CommandTabs`, `Details`, `Example`, `ExtractedTypeTable`, `File`, `FileTree`, `Folder`, `Mermaid`, `Prompt`, `Section`, `Selector`, `Step`, `Steps`, `Tab`, `Tabs`, `TopicSwitcher`, `TypeTable`.

If your app uses different names, you have two options: rename to match, or add a custom remark plugin that maps your names back to the contract above.

Runtime registration, heading IDs, and "On this page" sidebars are docs-app concerns. See [Render MDX and TOC](/docs/build/render-mdx-and-toc) for that setup.

## Reuse shared content

Use include tags when several pages need the same explanation, warning, setup step, or code sample. `leadtype generate` and `leadtype lint` handle includes automatically. Add `remarkInclude` before the default plugin stack in custom conversion scripts:

```ts
import { defaultRemarkPlugins, remarkInclude } from "leadtype/remark";

remarkPlugins: [remarkInclude, ...defaultRemarkPlugins];
```

Include a whole markdown or MDX partial with `src` or text content:

```mdx
<include src="./shared/session-flow.mdx" />

<include>./shared/session-flow.mdx</include>
```

You can also include code files. Leadtype emits them as fenced code blocks:

```mdx
<include src="../examples/session.ts" />

<include src="../examples/env" lang="bash" />
```

To reuse only one block from a larger file, append `#section-id` and wrap that block in a lowercase HTML `section`:

```mdx
<include src="./shared/auth.mdx#session-flow" />
```

```mdx
<section id="session-flow">
  This content can be reused in multiple pages.
</section>
```

Section reuse matches lowercase `<section id="...">` only. A capitalized `<Section id="...">` component is flattened later for markdown output, but it is not an include anchor.

Relative paths resolve from the including file first. Nested includes are supported, so a shared partial can include files next to itself. See [Remark plugins](/docs/reference/remark#remarkinclude) for base paths and plugin details.

## Component reference

Each section below shows the authored MDX and a live render.

### Callout

Wraps supporting context, warnings, or tips. Variants change styling but flatten identically into a blockquote.

```tsx
<Callout title="Heads up" variant="info">
  Body content goes here.
</Callout>
```

> ℹ️ **Info:** **Heads up**
> Callouts wrap supporting context, warnings, or tips. The remark pipeline flattens them into blockquotes so agents still see the content.
>
> ⚠️ **Warning:** **Don't do this**
> Variants like warning, success, error, and tip change the styling but flatten identically.

### Cards

A grid of short, linked entry points. Flattens to a bullet list of links.

```tsx
<Cards>
  <Card title="Convert" description="Turn MDX into agent-friendly markdown." href="/docs/reference/convert" />
</Cards>
```

* [Convert](/docs/reference/convert)
* [Remark](/docs/reference/remark)
* [Search](/docs/reference/search)

### Steps

Numbered walkthroughs. Flattens to an ordered list with bold step titles.

```tsx
<Steps>
  <Step title="Author docs in MDX">Use the components in this list.</Step>
  <Step title="Run the conversion">`leadtype generate` writes flattened markdown.</Step>
</Steps>
```

1. **Author docs in MDX** Use the components in this list as authoring affordances.

2. **Run the conversion** `leadtype generate` writes flattened markdown to `public/docs/`.

3. **Serve both formats** HTML for humans, `.md` for agents — same URL, content negotiated by the `Accept` header.

### Tabs

Group equivalent content. Flattens to bold headings followed by content so agents do not need a JSX-aware renderer to read every variant.

```tsx
<Tabs items={["TanStack Start", "Next.js", "Vite"]}>
  <Tab value="tanstack-start">…</Tab>
  <Tab value="next-js">…</Tab>
  <Tab value="vite">…</Tab>
</Tabs>
```

**tanstack-start**

Use a Vite middleware (dev/preview) and a Nitro middleware (prod) to negotiate the `Accept` header.

**next-js**

Wire content negotiation in middleware.ts and serve `.md` from a route handler.

**vite**

A `configureServer` middleware is enough for static deployments where `.md` files live in `public/`.

### CommandTabs

Package-manager-aware install or run commands. Flattens to a markdown table with one row per manager.

Use `mode="install"` when `command` is a package name, `mode="run"` when `command` is a CLI name, and `mode="create"` for starter commands. Use the `commands` prop for exact per-manager overrides.

```tsx
<CommandTabs command="leadtype" mode="install" />
<CommandTabs command="leadtype lint" mode="run" />
<CommandTabs
  commands={{ npm: "npm install leadtype", pnpm: "pnpm add leadtype" }}
  defaultManager="pnpm"
/>
```

|Package manager|Command|
|:--|:--|
|npm|`npm install leadtype`|
|pnpm|`pnpm add leadtype`|
|yarn|`yarn add leadtype`|
|bun|`bun add leadtype`|

|Package manager|Command|
|:--|:--|
|npm|`npx leadtype lint`|
|pnpm|`pnpm dlx leadtype lint`|
|yarn|`yarn dlx leadtype lint`|
|bun|`bunx leadtype lint`|

### Prompt

Displays an agent-ready prompt with a copy action. Flattening preserves the prompt body as a fenced `prompt` block so copied instructions also survive in `.md`, root `llms-full.txt`, and bundled `AGENTS.md` output.

```tsx
<Prompt title="Copy prompt for your coding agent" description="Use this after generating artifacts.">
  Inspect `public/docs/agent-readability.json`, then wire markdown responses before the HTML docs route.
</Prompt>
```

**Copy prompt for your coding agent**

Use this after generating artifacts.

```prompt
Inspect `public/docs/agent-readability.json`, then wire markdown responses before the HTML docs route.
```

### Audience

Splits browser-only and agent-only guidance without forking the page. Human content renders in the docs UI and is omitted from markdown output; agent content is hidden in the browser and included in generated markdown.

```tsx
<Audience target="human">Click the robot icon in the header.</Audience>
<Audience target="agent">Read generated markdown before editing runtime routes.</Audience>
```

This sentence appears only in generated markdown for agents.

### FileTree

Shows project structure in guides and release instructions. Flattening emits a fenced text tree so agents can read the same hierarchy without JSX.

```tsx
<FileTree root="public">
  <File name="llms.txt" />
  <Folder name="docs">
    <File name="index.md" />
  </Folder>
</FileTree>
```

```text
public/
├── llms.txt
└── docs/
    └── index.md
```

### Accordion

Collapsible details for secondary content. Flattening ignores open/closed state and emits every item — accordions are not a place to hide content from agents.

```tsx
<Accordion>
  <AccordionItem title="When should I use accordions?">
    Use them for supporting details and optional reference material.
  </AccordionItem>
</Accordion>
```

**When should I use accordions?**

Use them for supporting details, troubleshooting notes, and optional reference material. Closed content is still flattened by the remark pipeline.

**Are accordions a good place to hide content from LLMs?**

No. Conversion ignores the open/closed state and emits everything inside.

### TopicSwitcher

Navigation across equivalent docs topics — frameworks, SDKs, runtimes, deployment targets, product areas. Reader-facing only; it does not automatically read LLM topic config.

```tsx
<TopicSwitcher
  label="Framework"
  activeValue="react"
  items={[
    { value: "react", label: "React", href: "/docs/frameworks/react" },
    { value: "vue", label: "Vue", href: "/docs/frameworks/vue" },
  ]}
/>
```

Framework

* [React](/docs/authoring/components) — React integration
* [Vue](/docs/authoring/components) — Vue integration
* [Svelte](/docs/authoring/components) — Svelte integration

### TypeTable and ExtractedTypeTable

`TypeTable` is for explicit prop or type rows you already know. `ExtractedTypeTable` reads a TypeScript file at conversion time and extracts the table from a named type — keep its `path` stable.

```tsx
<TypeTable
  properties={{
    title: { type: "string", required: true, description: "Heading rendered above the body." },
    variant: { type: "CalloutVariant", default: "info", description: "Visual treatment." },
  }}
/>
```

|Property|Type|Description|Default|Required|
|:--|:--|:--|:--|:--:|
|title|string|Heading rendered above the callout body.|-|✅ Required|
|variant|CalloutVariant|Visual treatment for the callout.|info|Optional|
|deprecated|\~\~boolean\~\~ (deprecated)|Marks the row as deprecated.|false|Optional|

### Example

Data-driven preview and source examples. The host component receives code as data; add file loaders or dynamic imports outside leadtype when an example needs app-specific behavior.

```tsx
<Example
  title="Render MDX"
  description="Preview the output and inspect the source."
  filename="mdx-components.tsx"
  language="tsx"
  code={`import { mdxComponents } from "@/components/docs-mdx";`}
>
  <Callout title="Runtime components" variant="success">
    The host app owns styling and runtime components while leadtype owns conversion.
  </Callout>
</Example>
```

### Mermaid

Diagrams authored as plain text. Renders client-side as interactive SVG. Flattening preserves the source as a fenced ` ```mermaid ` block so other tools can render the diagram from the markdown copy.

```tsx
<Mermaid chart={`graph LR
  MDX -->|remark| Markdown
  Markdown -->|llms.txt| Agents`} />
```

```mermaid
`graph LR
MDX -->|remark| Markdown
Markdown -->|search index| API
Markdown -->|llms.txt| Agents`
```

## Guidelines

* Keep runtime components in your docs app. Leadtype stays out of UI.
* Keep component names stable. Renaming `<Callout>` breaks the flattening contract until you add a remark plugin to remap.
* For agent output quality, read the converted `.md` files first and only edit components or plugin order if the markdown actually looks wrong.
