---
title: Format text
description: Headings, emphasis, links, quotes, line breaks and escaping, and what Reed's MDX does and does not render.
---

Reed pages are MDX: markdown with JSX mixed in. Most of what you write is plain markdown,
and it renders the way you expect. The exceptions are where MDX is stricter than markdown,
and a few markdown extensions that Reed does not turn on. This page covers both.

## Headings

Your frontmatter `title` is the page's H1. Start body headings at `##`:

```mdx
---
title: Webhooks
description: Receive events from the platform as HTTP callbacks.
---

## Register an endpoint

### Verify the signature

#### Rotate the secret
```

Two rules are enforced as `DS-A02` errors, and either one fails the build:

- **No H1 in the body.** A `# Heading` would render a second top-level heading beside the
  title.
- **No skipped levels.** Going from `##` straight to `####` breaks the outline a screen
  reader navigates by.

Use `##` for main sections and `###` for subsections. You can go deeper, but if you need
`####` often, the page is probably doing too much.

### Anchor IDs

Every heading gets an ID generated from its text: `## Register an endpoint` becomes
`#register-an-endpoint`. Link to it from the same page with `[text](#register-an-endpoint)`,
or from another page with the full path and the fragment.

You cannot set a custom ID. The `## Heading {#custom-id}` syntax some platforms accept is
parsed by MDX as a JavaScript expression, and the page fails with `unparseable-mdx`. If an
anchor has to stay stable, keep the heading text stable.

## Emphasis and inline code

| Syntax | Renders as |
|---|---|
| `**bold**` | **bold** |
| `*italic*` or `_italic_` | *italic* |
| `***bold italic***` | ***bold italic*** |
| `~~strikethrough~~` | ~~strikethrough~~ |
| `` `inline code` `` | `inline code` |

Use bold for the few words a skimming reader must not miss, not for whole sentences. Use
inline code for anything the reader might type or search for: file names, commands,
option names, values.

A handful of HTML inline elements work as written, including `<sup>`, `<sub>`, `<kbd>`
and `<u>`:

```mdx
Press <kbd>Ctrl</kbd> + <kbd>C</kbd> to stop the server. E = mc<sup>2</sup>.
```

## Links

Write links with standard markdown syntax:

```mdx
See the [Quickstart](/docs/quickstart) for setup.
Read the [MDX specification](https://mdxjs.com/docs/what-is-mdx/).
```

**Reed does not rewrite links you write in prose.** If your site sets `base`, every
root-relative link must include it. On a site mounted at `/docs`, `/docs/quickstart` is
correct and `/quickstart` compiles without a warning and 404s in production. The same
applies to `href` on components such as `Card`. See
[How to link documentation pages effectively](/docs/guides/linking) for the full rule and
how to check it mechanically.

Bare URLs become links on their own. `https://example.com` and `www.example.com` both
render as clickable links. The angle-bracket form, `<https://example.com>`, does **not**
work: MDX reads it as a JSX tag and the page fails to parse.

A title in quotes after the URL becomes the link's `title` attribute:

```mdx
[Status page](https://status.example.com "Current incidents")
```

## Blockquotes

Prefix each line with `>`. A line with only `>` separates paragraphs inside the quote:

```mdx
> Webhooks are delivered at least once.
> Your handler must tolerate duplicates.
>
> Use the event ID to deduplicate.
```

Consecutive `>` lines join into one paragraph, the same as ordinary markdown lines. For a
note, warning or tip, use a [callout component](/docs/authoring/components) instead. A
callout carries its intent visually; a blockquote does not.

## Horizontal rules

Three hyphens on their own line, with a blank line above, render a horizontal rule:

```mdx
Previous section text.

---

Next section text.
```

Prefer a heading. A rule separates content without telling the reader what comes next,
and it does not appear in the table of contents.

## Line breaks

A single newline inside a paragraph is not a line break. The lines are joined with a
space. Leave a blank line to start a new paragraph.

To break a line without starting a paragraph, end the line with a backslash, end it with
two trailing spaces, or write `<br />`:

```mdx
Acme Inc.\
100 Main Street

Line one<br />Line two
```

Prefer the backslash. Trailing spaces are invisible and editors often strip them. Write
`<br />` with the slash: MDX requires every tag to be closed, and `<br>` on its own fails
to parse.

## Collapsible sections

The HTML `<details>` element works, with blank lines around the markdown inside it:

```mdx
<details>
<summary>Why is the first request slow?</summary>

The first request warms the connection pool.

</details>
```

For anything more than an occasional aside, use `Accordion`, which is styled to match the
rest of the page. See [Layout and surfaces](/docs/reference/components/layout).

## HTML and JSX

MDX accepts HTML elements, but parses them as JSX. That changes a few things:

- Every tag must be closed: `<br />`, `<img ... />`, `<hr />`.
- Write inline styles as an object: `style={{color: 'red'}}`. That is the form tested
  with Reed; the string form `style="color: red"` has not been checked.
- HTML comments do not work. `<!-- note -->` fails to parse. Use a JSX comment instead,
  which renders nothing:

```mdx
{/* TODO: add the rate-limit table once the numbers are final */}
```

An HTML element on its own line is a block, and the text inside it is wrapped in a
paragraph. Keep raw HTML to a minimum. Most of what people reach for it to do, a catalog
component does with better styling and a checked contract.

## Escape special characters

MDX gives `{`, `}` and `<` a meaning that plain markdown does not.

**Braces** open a JavaScript expression. `{1 + 1}` in prose renders as `2`, and an
unbalanced `{` fails to parse. To show a literal brace, escape it with a backslash:

```mdx
Replace \{project_id\} with your project's ID.
```

Inside inline code and fenced code blocks, braces are literal and need no escaping. That
is usually the better fix: a placeholder such as `{project_id}` belongs in code
formatting anyway.

**Angle brackets** start a tag when followed by a letter, `/` or `!`. `a < b`, with a
space, is fine. `a <b` and `1<2` fail to parse. Escape with a backslash, `\<`, or use the
entity `&lt;`. Again, inline code is often the right answer: `<Card>` in backticks needs
no escaping.

**Markdown characters** such as `*`, `_` and `#` are escaped with a backslash, as in
standard markdown: `\*not italic\*`.

## What does not render

These markdown extensions are common on other platforms. In Reed they build without an
error but render as literal text:

| Syntax | What you get |
|---|---|
| Footnotes, `text[^1]` and `[^1]: note` | The literal `[^1]` and the note as a plain paragraph |
| Task lists, `- [ ] item` | A bullet with the literal text `[ ] item` |
| Math, `$x^2$` and `$$ ... $$` blocks | The literal dollar signs and source |

Two more fail the build instead of rendering literally: custom heading IDs
(`{#custom-id}`) and angle-bracket autolinks (`<https://...>`), both covered above.

If you need a footnote, write the note as a parenthetical or a sentence at the end of
the section. For a checklist, use an ordinary list, or `Steps` when the order matters.

## Related

- [Format code](/docs/authoring/formatting/code)
- [Lists and tables](/docs/authoring/formatting/lists-and-tables)
- [MDX pitfalls](/docs/authoring/mdx-pitfalls)
- [Diagnostics](/docs/reference/diagnostics)
