> ## Documentation Index
> Fetch the complete documentation index at: https://anvil.servicetitan.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Markdown - Web

> Markdown renders formatted text content from agent responses.

> [!NOTE]
>
> For development, import `Markdown` from
> `@servicetitan/anvil2-ai-kit`. For design, find it in the
> [AI Kit Web Component Library file](https://www.figma.com/design/QEIsArLktLeJAaFvcpw3PO/AI-Kit-Web-Component-Library).

ai-kit-markdown

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-markdown?file=src/App.tsx)

```tsx lines theme={null}
import { Markdown } from "@servicetitan/anvil2-ai-kit";

const source = [
  "# Page title",
  "",
  "A paragraph with **bold**, *emphasis*, and a [link](https://example.com).",
  "",
  "Inline `code` sits between words.",
].join("\n");

function App() {
  return (
    <div style={{ maxWidth: "44rem" }}>
      <Markdown source={source} />
    </div>
  );
}

export default App;
```

## Options

Markdown renders GitHub Flavored Markdown source into Carto-styled HTML — headings, inline formatting, lists, code, quotes, and tables.

### Basic text

ai-kit-markdown-basic-text

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-markdown-basic-text?file=src/App.tsx)

```tsx lines theme={null}
import { Markdown } from "@servicetitan/anvil2-ai-kit";

const source = [
  "Plain paragraph text.",
  "",
  "**Bold text** emphasizes a word or phrase.",
  "",
  "*Italicized text* adds a lighter emphasis.",
  "",
  "~~Strikethrough text~~ marks something as removed or done.",
].join("\n");

function App() {
  return (
    <div style={{ maxWidth: "44rem" }}>
      <Markdown source={source} />
    </div>
  );
}

export default App;
```

Bold (`**text**`) and italic (`*text*`) are standard CommonMark. Standard markdown has no distinct underline syntax, so strikethrough (`~~text~~`, GitHub Flavored Markdown) is the closest additional emphasis available.

### Headings

ai-kit-markdown-headings

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-markdown-headings?file=src/App.tsx)

```tsx lines theme={null}
import { Markdown } from "@servicetitan/anvil2-ai-kit";

const source = [
  "# Heading 1",
  "## Heading 2",
  "### Heading 3",
  "#### Heading 4",
].join("\n");

function App() {
  return (
    <div style={{ maxWidth: "44rem" }}>
      <Markdown source={source} />
    </div>
  );
}

export default App;
```

Four heading levels map to `Text`'s headline sizes: `h1` renders `hero`, `h2` renders `major`, `h3` renders `substantial`, and `h4` renders `regular`. `h5` and `h6` also render but reuse the `regular` size, relying on the semantic tag alone to signal depth.

### Inline Formatting

ai-kit-markdown-inline-formatting

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-markdown-inline-formatting?file=src/App.tsx)

```tsx lines theme={null}
import { Markdown } from "@servicetitan/anvil2-ai-kit";

const source =
  "A paragraph with **bold**, *emphasis*, `inline code`, and a [link](https://example.com).";

function App() {
  return (
    <div style={{ maxWidth: "44rem" }}>
      <Markdown source={source} />
    </div>
  );
}

export default App;
```

Bold, italic, inline code, and links combine freely within a single line of prose.

### Lists

ai-kit-markdown-lists

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-markdown-lists?file=src/App.tsx)

```tsx lines theme={null}
import { Markdown } from "@servicetitan/anvil2-ai-kit";

const source = [
  "- First item",
  "- Second item",
  "  - Nested item",
  "",
  "1. First step",
  "2. Second step",
  "",
  "- [x] Completed task",
  "- [ ] Open task",
].join("\n");

function App() {
  return (
    <div style={{ maxWidth: "44rem" }}>
      <Markdown source={source} />
    </div>
  );
}

export default App;
```

Unordered and ordered lists nest to any depth. GitHub Flavored Markdown task lists (`- [x]` / `- [ ]`) render as read-only checkboxes reflecting each item's completion — they aren't interactive.

### Code

ai-kit-markdown-code

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-markdown-code?file=src/App.tsx)

````tsx lines theme={null}
import { Markdown } from "@servicetitan/anvil2-ai-kit";

const source = [
  "Inline `code` sits between words.",
  "",
  "```ts",
  "function greet(name: string) {",
  "  return `Hello, ${name}!`;",
  "}",
  "```",
].join("\n");

function App() {
  return (
    <div style={{ maxWidth: "44rem" }}>
      <Markdown source={source} />
    </div>
  );
}

export default App;
````

Inline code uses a tile background. Fenced code blocks (` ``` `) render in a bordered surface; Markdown doesn't syntax-highlight by language.

### Quotes

ai-kit-markdown-quotes

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-markdown-quotes?file=src/App.tsx)

```tsx lines theme={null}
import { Markdown } from "@servicetitan/anvil2-ai-kit";

const source = [
  "> A blockquote sets quoted text apart from the surrounding prose.",
  "",
  "---",
  "",
  "A horizontal rule separates unrelated sections of content.",
].join("\n");

function App() {
  return (
    <div style={{ maxWidth: "44rem" }}>
      <Markdown source={source} />
    </div>
  );
}

export default App;
```

A blockquote (`>`) indents quoted prose with a leading rule. A horizontal rule (`---`) separates unrelated sections of content.

### Tables

ai-kit-markdown-tables

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-markdown-tables?file=src/App.tsx)

```tsx lines theme={null}
import { Markdown } from "@servicetitan/anvil2-ai-kit";

const source = [
  "| Language | Typing | Use Case |",
  "| -------- | ------ | -------- |",
  "| TypeScript | Static (Strong) | Web / Scalable Apps |",
  "| Python | Dynamic | AI / Data Science |",
  "| Rust | Static (Safe) | Systems / WebAssembly |",
].join("\n");

function App() {
  return (
    <div style={{ maxWidth: "44rem" }}>
      <Markdown source={source} />
    </div>
  );
}

export default App;
```

Tables (GitHub Flavored Markdown) render as a read-only chat table: a bordered header row, compact body cells, and a 265px height cap. Extra columns or rows scroll inside the table; the header stays in view and overflow fades appear when more content remains. Cells accept bold, italic, and links.

## Behavior

Markdown is presentational — the only interactive element it can render is a link, and task-list checkboxes are read-only. Tall or wide tables scroll inside the table region rather than expanding the chat column.

## Usage Guidelines

### When to Use

Use the Markdown when:

* **Rendering agent responses** – The agent returns markdown source with headings, emphasis, lists, code, or quotes.
* **Showing a table in the conversation** – A response includes a table. Markdown renders it as a read-only table that scrolls within a fixed height.
* **Formatting a dialog body** – A Dialog message needs formatted text. Pass rendered Markdown as the Dialog content.

### When not to use

Avoid using the Markdown for:

* **Styling single-block copy** – A headline, body copy, or label needs no lists, tables, code, or quotes. Use the [Text](https://anvil.servicetitan.com/docs/components/text/ai-kit.md) instead.
* **Collecting selections from a checklist** – Markdown task lists are read-only. Use the [Checkbox](https://anvil.servicetitan.com/docs/components/checkbox/ai-kit.md) instead.

## Keyboard Interaction

Users can navigate and activate any link rendered within the Markdown using standard keyboard controls. Overflowing tables expose a focusable scroll region so keyboard users can pan the table.

| Key | Description |
| - | - |
| Tab | Moves focus to the next link or table scroll region |
| Arrow keys | Scroll a focused table region |
| Enter | Activates the focused link's `href` |

## Code

**Implementation**

ai-kit-markdown

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-markdown?file=src/App.tsx)

```tsx lines expandable theme={null}
import { Markdown } from "@servicetitan/anvil2-ai-kit";

const source = [
  "# Page title",
  "",
  "A paragraph with **bold**, *emphasis*, and a [link](https://example.com).",
  "",
  "Inline `code` sits between words.",
].join("\n");

function App() {
  return (
    <div style={{ maxWidth: "44rem" }}>
      <Markdown source={source} />
    </div>
  );
}

export default App;
```

## Common Examples

To use the `Markdown`, import it from `@servicetitan/anvil2-ai-kit` and pass a required markdown string through `source`. The kit forbids `children`.

```tsx theme={null}
import { Markdown } from "@servicetitan/anvil2-ai-kit";

function ExampleComponent() {
  return <Markdown source={"# Summary\n\nCompleted **3 tasks**."} />;

}
```

`Markdown` enables GitHub Flavored Markdown, including tables, strikethrough, task lists, and autolinks.

### Headings

Headings render through [`Text`](https://anvil.servicetitan.com/docs/components/text/react-native) so semantic levels and the Carto headline scale remain aligned.

ai-kit-markdown-headings

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-markdown-headings?file=src/App.tsx)

```tsx lines expandable theme={null}
import { Markdown } from "@servicetitan/anvil2-ai-kit";

const source = [
  "# Heading 1",
  "## Heading 2",
  "### Heading 3",
  "#### Heading 4",
].join("\n");

function App() {
  return (
    <div style={{ maxWidth: "44rem" }}>
      <Markdown source={source} />
    </div>
  );
}

export default App;
```

### Inline formatting

Markdown supports emphasis, strong text, strikethrough, inline code, and links.

ai-kit-markdown-inline-formatting

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-markdown-inline-formatting?file=src/App.tsx)

```tsx lines expandable theme={null}
import { Markdown } from "@servicetitan/anvil2-ai-kit";

const source =
  "A paragraph with **bold**, *emphasis*, `inline code`, and a [link](https://example.com).";

function App() {
  return (
    <div style={{ maxWidth: "44rem" }}>
      <Markdown source={source} />
    </div>
  );
}

export default App;
```

### Lists and task lists

Ordered and unordered lists support nesting. GitHub task-list checkboxes are read-only.

ai-kit-markdown-lists

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-markdown-lists?file=src/App.tsx)

```tsx lines expandable theme={null}
import { Markdown } from "@servicetitan/anvil2-ai-kit";

const source = [
  "- First item",
  "- Second item",
  "  - Nested item",
  "",
  "1. First step",
  "2. Second step",
  "",
  "- [x] Completed task",
  "- [ ] Open task",
].join("\n");

function App() {
  return (
    <div style={{ maxWidth: "44rem" }}>
      <Markdown source={source} />
    </div>
  );
}

export default App;
```

### Code

Inline code and fenced code blocks receive separate Carto treatments.

ai-kit-markdown-code

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-markdown-code?file=src/App.tsx)

````tsx lines expandable theme={null}
import { Markdown } from "@servicetitan/anvil2-ai-kit";

const source = [
  "Inline `code` sits between words.",
  "",
  "```ts",
  "function greet(name: string) {",
  "  return `Hello, ${name}!`;",
  "}",
  "```",
].join("\n");

function App() {
  return (
    <div style={{ maxWidth: "44rem" }}>
      <Markdown source={source} />
    </div>
  );
}

export default App;
````

### Tables

GitHub Flavored Markdown tables render through the kit's responsive table implementation.

ai-kit-markdown-tables

[StackBlitz demo](https://stackblitz.com/github/servicetitan/anvil2-docs-live-code/tree/main/examples/ai-kit-markdown-tables?file=src/App.tsx)

```tsx lines expandable theme={null}
import { Markdown } from "@servicetitan/anvil2-ai-kit";

const source = [
  "| Language | Typing | Use Case |",
  "| -------- | ------ | -------- |",
  "| TypeScript | Static (Strong) | Web / Scalable Apps |",
  "| Python | Dynamic | AI / Data Science |",
  "| Rust | Static (Safe) | Systems / WebAssembly |",
].join("\n");

function App() {
  return (
    <div style={{ maxWidth: "44rem" }}>
      <Markdown source={source} />
    </div>
  );
}

export default App;
```

### Links

Relative and same-origin links stay in the current tab. External HTTP(S) links open in a new tab with `rel="noopener noreferrer"`.

## React Accessibility

* Markdown headings preserve their source heading levels.
* Images use their markdown alt text. Images without alt text render with an empty `alt` attribute.
* Task-list checkboxes are disabled because rendered markdown is read-only.
* Tables preserve header and data-cell semantics.

**Markdown Props**

```tsx theme={null}
<Markdown source={"# Summary\n\nCompleted **3 tasks**."} />

```

## `Markdown` Props

The `Markdown` accepts the following props and forwards remaining `<div>` attributes except `children` and `style`.

**source** `string` *required*

Markdown source parsed with GitHub Flavored Markdown enabled.

**className** `string`

Class merged onto the root wrapper.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.