Skip to content

Alpine.js x-html Directive — Complete Guide with Examples

DodaTech Updated 2026-06-28 5 min read

In this tutorial, you'll learn about the Alpine.js x-html directive. We cover key concepts, practical examples, and best practices to help you understand and apply this topic effectively.

The Alpine.js x-html directive sets an element's innerHTML to the result of a JavaScript expression, rendering HTML tags rather than escaping them.

What You'll Learn

By the end of this tutorial, you'll use x-html to render dynamic HTML content, understand the security implications, sanitize user input, and know when to use x-html vs x-text.

Why It Matters

Sometimes your data contains HTML that needs to be rendered as formatted content: rich text from a CMS, formatted error messages, or dynamic SVG icons. x-html gives you the power to render HTML directly, but with great power comes great responsibility.

Real-World Use

DodaZIP's file preview feature uses x-html to render rich file descriptions that include formatting, links, and inline images. The descriptions come from a trusted source, so x-html is safe to use.

Where This Fits in Your Learning Path

flowchart LR
    A["x-text Directive"] --> B["**x-html Directive**"]
    B --> C["x-ref Directive"]
    C --> D["x-teleport Directive"]
    D --> E["Advanced Alpine Patterns"]
    style B fill:#f97316,stroke:#c2410c,color:#fff
    style A fill:#e5e7eb,stroke:#9ca3af,color:#374151
    style E fill:#22c55e,stroke:#16a34a,color:#fff

What is x-html?

x-html sets the innerHTML of an element. Unlike x-text, it does NOT escape HTML tags. The expression's result is parsed as HTML and inserted into the DOM.

Think of x-html like a stamp that prints formatted text. Give it "bold" and the output is bold. But if someone hands you a stamp that says "", it runs that code. You must trust where the stamp comes from.

<div x-data="{ content: '<strong>Important:</strong> This is <em>emphasized</em>' }">
  <div x-html="content"></div>
</div>

Expected output: "Important: This is emphasized" with "Important:" in bold and "emphasized" in italics.

Rendering Rich Text from APIs

When fetching formatted content from a trusted API, x-html renders it properly.

<div x-data="{ article: '<h2>Hello World</h2><p>This is a <a href=\"/page\">link</a> in the content.</p>' }">
  <article x-html="article"></article>
</div>

Expected output: The article content with proper heading, paragraph, and link rendering.

Rendering SVG Dynamically

x-html can inject SVG markup into the DOM.

<div x-data="{ icon: '<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"green\"><circle cx=\"12\" cy=\"12\" r=\"10\"/></svg>' }">
  <div x-html="icon"></div>
</div>

Expected output: A green outlined circle rendered as inline SVG.

Security Considerations

Never use x-html with user-generated content without sanitization. x-html does NOT escape HTML, so malicious scripts can execute.

<!-- DANGEROUS: never render user input with x-html -->
<div x-data="{ userComment: '<img src=x onerror=alert(1)>' }">
  <div x-html="userComment"></div>
</div>

Expected output: An alert box pops up. This demonstrates why x-html must only be used with trusted content.

Common Mistakes

1. Using x-html with user input

Always sanitize user input server-side before using x-html. Better yet, use x-text for user content and reserve x-html for trusted content.

2. Expecting x-html to update when only part of the HTML changes

x-html replaces the entire innerHTML. If only a small part changes, the entire subtree is recreated, potentially losing state.

3. Using x-html on the same element as x-text

These directives conflict. Use one or the other per element.

4. Forgetting that x-html removes Alpine bindings

Replaced content is not processed by Alpine unless you use x-init to reinitialize.

5. Using x-html with malformed HTML

If the expression returns broken HTML (missing closing tags), it can break the page layout.

Practice Questions

  1. What is the key difference between x-html and x-text? x-html sets innerHTML (renders tags). x-text sets innerText (escapes tags).

  2. Why is x-html dangerous with user input? It can execute malicious scripts embedded in the HTML, leading to XSS Attacks.

  3. Can x-html render SVG? Yes. SVG markup passed to x-html is rendered as inline SVG elements.

  4. Does Alpine Process directives inside x-html content? No. Content inserted via x-html is not bootstrapped by Alpine. Use x-init if needed.

  5. What happens if x-html evaluates to null? The element's innerHTML is cleared.

Challenge

Build a safe HTML renderer that accepts a string of HTML, sanitizes it by removing script tags and event handlers using JavaScript, and then renders the safe result with x-html.

FAQ

Can I use x-html to load external scripts?

Technically yes, but scripts inserted via innerHTML do not execute. You would need to create and append script elements via JavaScript.

How do I sanitize HTML before using x-html?

Use a library like DOMPurify or write a sanitization function that strips script tags and event handler attributes.

Does x-html work with iframes?

Yes. You can inject iframe HTML, but the iframe's content is subject to the same-origin policy.

What is the performance impact of x-html?

Replacing innerHTML destroys all child DOM nodes and recreates them. For large content, use x-show to toggle visibility instead.

Can x-html be used with x-transition?

Yes. Wrap the x-html element with a container that has x-transition for enter/leave animations on content changes.


Mini Project

Build a rich text preview panel. A textarea accepts HTML input. A preview div uses x-html to render it. Include a sanitize button that strips dangerous tags before rendering.

<div x-data="{ rawHTML: '<h2>Hello</h2><p>This is <b>bold</b> and <i>italic</i></p>', sanitized: '' }">
  <textarea x-model="rawHTML" rows="4" class="w-full p-2 border rounded font-mono text-sm"></textarea>
  <div class="mt-4 flex gap-2">
    <button @click="sanitized = rawHTML" class="px-4 py-2 bg-blue-500 text-white rounded">Render HTML</button>
    <button @click="sanitized = rawHTML.replace(/<script[^>]*>.*?<\/script>/gi, '').replace(/\son\w+="[^"]*"/gi, '')" class="px-4 py-2 bg-green-500 text-white rounded">Sanitize & Render</button>
  </div>
  <div class="mt-4 p-4 border rounded bg-white">
    <h3 class="font-bold mb-2">Preview:</h3>
    <div x-html="sanitized" class="prose"></div>
  </div>
</div>

What's Next

Move on to DOM references:

Tutorial What You'll Learn
x-ref Directive Reference DOM elements directly
x-teleport Directive Teleport elements to other locations

Related topics: innerHTML security risks, XSS prevention.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro