Alpine.js x-html Directive — Complete Guide with Examples
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
What is the key difference between x-html and x-text? x-html sets innerHTML (renders tags). x-text sets innerText (escapes tags).
Why is x-html dangerous with user input? It can execute malicious scripts embedded in the HTML, leading to XSS Attacks.
Can x-html render SVG? Yes. SVG markup passed to x-html is rendered as inline SVG elements.
Does Alpine Process directives inside x-html content? No. Content inserted via x-html is not bootstrapped by Alpine. Use x-init if needed.
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
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