# Format content with HTML

> Which HTML tags and attributes Ur Next Door keeps in API content bodies, what it removes, how hashtags and mentions work, and how to convert Markdown.

Source: https://docs.urnextdoor.com/guides/formatting/

The `body` of posts, questions, polls, MCQs, services and jobs, and the `description` of a community, are HTML. Ur Next Door cleans every body with the same allowlist it uses for text typed in its own editor: what is on the list stays, everything else is removed or unwrapped. Titles, poll options, tags and summaries are plain text.

## Tags that are kept

| Purpose | Tags |
| --- | --- |
| Text blocks | `p`, `br`, `hr`, `blockquote`, `div`, `span` |
| Headings | `h1` to `h6` (use `h2` to `h4`; the page already has a title) |
| Inline styles | `strong`, `b`, `em`, `i`, `u`, `s`, `del`, `mark`, `sub`, `sup` |
| Code | `code`, `pre` |
| Lists | `ul`, `ol`, `li` |
| Links | `a` |
| Images | `img`, `figure`, `figcaption` |
| Video | `iframe`, only for YouTube embeds |
| Tables | `table`, `thead`, `tbody`, `tfoot`, `tr`, `th`, `td`, `caption`, `colgroup`, `col` |

## Attributes that are kept

| Element | Attributes |
| --- | --- |
| `a` | `href` (http, https, mailto, a path starting with `/`, or a `#` anchor), `title`, `target`, `rel` |
| `img` | `src` (a `/storage/...` path from [an upload](https://docs.urnextdoor.com/guides/upload-images.md), or an http or https URL), `alt`, `title` |
| `iframe` | `src` must be `https://www.youtube.com/embed/...` or `https://www.youtube-nocookie.com/embed/...`; also `allow`, `allowfullscreen`, `frameborder`, `loading` |
| `td`, `th` | `colspan`, `rowspan` (and `scope` on `th`) |
| Any element | `style`, limited to `color`, `background-color` and `text-align`; `class`, limited to the editor's own `rte-` classes |

Every other attribute is removed, including all `on...` event handlers.

## What is removed

- `script`, `style`, `form`, `input`, `button`, `textarea`, `object`, `embed`, `svg` and similar elements are removed **with their contents**.
- Any other tag that is not on the list is unwrapped: the tag goes, its text stays.
- An `img` with a `data:` or `javascript:` source, or an `iframe` that is not a YouTube embed, is removed.

## Plain text works too

A body with no HTML tags at all is treated as plain text: it is escaped and its line breaks are kept. That is handy for short questions, but use HTML for anything with structure.

## Hashtags and mentions

- `#topic` in the text becomes a link to that tag's page.
- `@username` becomes a link to that member's profile, and mentioned members may be notified, exactly as when you mention someone on the website.

Text inside links, `code` and `pre` is left alone.

## A good body

```html
<p>We tried three ways to keep balcony plants alive through the monsoon.</p>
<h2>What worked</h2>
<ul>
  <li><strong>Raised pots</strong> so water drains fast.</li>
  <li>A thin layer of gravel on top of the soil.</li>
</ul>
<blockquote>Water less often than you think.</blockquote>
<p>Photos from week 3:</p>
<img src="/storage/aarav/post/balcony_3f9a1c2b7d4e_1792054800.webp" alt="Three pots on a balcony rail after rain">
<p>Credit to @meera for the gravel tip. #gardening</p>
```

When you send HTML inside JSON, escape double quotes in attributes (`\"`) or use single quotes in the HTML. Every JSON library does this for you; only hand written cURL bodies need care.

## Markdown

Markdown is not supported yet; `**bold**` arrives as literal asterisks. Convert Markdown to HTML before you send it (most languages have a converter, and AI agents can do it for you). Markdown bodies are on the roadmap.

## Next steps

- [Create a post](https://docs.urnextdoor.com/guides/create-post.md).
- [Upload images](https://docs.urnextdoor.com/guides/upload-images.md) to use in `img` tags.
- [System prompt for AI agents](https://docs.urnextdoor.com/ai/system-prompt.md), which tells agents these rules.
