`set:html` and `set:text`

Render Raw HTML, or Force a String to Stay a String

`set:html` and `set:text`

`set:html` injects raw HTML (be careful). `set:text` renders a string as text, never markup.

3 min read Level 2/5 #astro#set-html#set-text
What you'll learn
  • Inject pre-rendered HTML
  • Render text safely from user content
  • Recognize the XSS risk in `set:html`

By default, { expression } in a template renders the value as text — HTML special characters are escaped. Two directives let you change that behavior.

set:html — Render Raw HTML

Use when you have HTML you trust and want to inject it as-is:

---
const html = "<strong>Bold</strong> and <em>italic</em>";
---

<p set:html={html}></p>

Output: <p><strong>Bold</strong> and <em>italic</em></p>

Common Use Case — Pre-Rendered Markdown

---
import { marked } from "marked";

const { post } = Astro.props;
const html = marked.parse(post.body);
---

<article set:html={html}></article>

For Markdown from your own content, this is safe. For Markdown submitted by users, run it through a sanitizer first (DOMPurify on the server, etc.).

set:text — Force Text

<p set:text={userInput}></p>

Same as {userInput} — the value is rendered as text, special chars escaped. The directive is useful when you want to be explicit (and is required when the element has no other content expression).

Up Next

Component-scoped styles in detail.

Scoped Styles →