Skip to content

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

DodaTech Updated 2026-06-28 6 min read

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

The Alpine.js x-if directive conditionally adds elements to the DOM by completely removing them when the expression is false and recreating them when true.

What You'll Learn

By the end of this tutorial, you'll use x-if with the template element, understand the difference from x-show, chain multiple x-if conditions, and know when x-if is the right tool.

Why It Matters

Some components are expensive to keep in memory. A video player, a complex chart, or a third-party widget consumes resources even when hidden. x-if removes them entirely, freeing memory and reducing the browser's layout and paint work.

Real-World Use

Durga Antivirus Pro's scan results page uses x-if for the detailed threat report panel. Opening it creates the panel fresh with the latest data. Closing it destroys the panel and frees all associated event listeners and DOM nodes.

Where This Fits in Your Learning Path

flowchart LR
    A["x-show Directive"] --> B["**x-if Directive**"]
    B --> C["x-for Directive"]
    C --> D["x-ref & x-teleport"]
    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-if?

x-if must be used on a <template> element. When the expression is true, Alpine renders the template's content into the DOM. When false, Alpine removes the content entirely.

Think of x-if like a trap door. When the expression is true, the trap door is closed and you can stand on it. When false, the door opens and everything on top falls away completely. Nothing remains.

<div x-data="{ showDetails: false }">
  <button @click="showDetails = !showDetails">Toggle Details</button>
  <template x-if="showDetails">
    <div class="p-4 bg-blue-50 rounded">
      <p>These details are completely removed when hidden</p>
    </div>
  </template>
</div>

Expected output: Clicking the button creates or destroys the details div entirely. Inspect the DOM to see it appear and disappear.

x-if with Multiple Elements

You can wrap any number of elements inside the template. All of them are added or removed as a group.

<div x-data="{ loggedIn: false }">
  <button @click="loggedIn = !loggedIn" x-text="loggedIn ? 'Logout' : 'Login'"></button>
  <template x-if="loggedIn">
    <div>
      <h2>Welcome back, Alice!</h2>
      <p>You have 3 unread messages.</p>
      <button @click="alert('Dashboard')">Go to Dashboard</button>
    </div>
  </template>
</div>

Expected output: When loggedIn is false, nothing inside the template exists. When true, all elements appear together.

x-if with x-for

x-if can wrap x-for to conditionally render entire lists.

<div x-data="{ showList: true, items: ['Apples', 'Bananas', 'Cherries'] }">
  <button @click="showList = !showList" x-text="showList ? 'Hide' : 'Show'"></button>
  <template x-if="showList">
    <ul>
      <template x-for="(item, index) in items" :key="index">
        <li x-text="item"></li>
      </template>
    </ul>
  </template>
</div>

Expected output: The entire list is created or destroyed as a unit. When hidden, none of the list item DOM nodes exist.

x-if vs x-show Deep Dive

<div x-data="{ show: false, counter: 0 }">
  <button @click="show = !show; counter++">Toggle (show: <span x-text="show"></span>)</button>

  <p>Toggle count: <span x-text="counter"></span></p>

  <!-- x-show keeps a counter in memory -->
  <div x-show="show" x-init="console.log('x-show initialized')">
    x-show element: counter is <span x-text="counter"></span>
  </div>

  <!-- x-if destroys and recreates -->
  <template x-if="show">
    <div x-init="console.log('x-if initialized')">
      x-if element: counter is <span x-text="counter"></span>
    </div>
  </template>
</div>

Expected output: The x-show element's x-init runs only once (on page load). The x-if element's x-init runs every time the expression becomes true. Check the console to see the difference.

Common Mistakes

1. Using x-if on a non-template element

<!-- Wrong: x-if must be on a <template> -->
<div x-if="condition">Content</div>

<!-- Correct: wrap with template -->
<template x-if="condition">
  <div>Content</div>
</template>

2. Expecting x-if to animate

x-if instantly removes and adds elements. Use x-show with x-transition for animations. x-if has no transition support.

3. Losing component state when x-if toggles

Since x-if destroys and recreates the element, any internal state (like form input values) is reset. Use x-show if you need to preserve state across toggles.

4. Nesting x-if inside itself

You can nest x-if, but each one needs its own template wrapper. This can lead to deeply nested templates that are hard to read.

5. Forgetting that x-init runs on every creation

If x-if creates an element that makes an API call via x-init, that call fires every time the condition becomes true, not just the first time.

Practice Questions

  1. What HTML element must x-if be used on? The <template> element. x-if only works on template tags.

  2. What happens to the DOM when x-if evaluates to false? The template's content is completely removed from the DOM. Not hidden, but destroyed.

  3. Why would you choose x-if over x-show? When you want to free memory, reset component state, or avoid running hidden element logic.

  4. Does x-if support multiple child elements? Yes. The template can contain any number of siblings, and they're all added or removed together.

  5. What happens to event listeners when x-if removes elements? They are garbage collected along with the DOM nodes, preventing memory leaks.

Challenge

Build a "detail view" system where clicking an item in a list uses x-if to show a full detail panel for that item. When you click a different item, the previous panel is destroyed and the new one is created. Use x-init in the detail panel to simulate fetching data.

FAQ

Can I use x-if on a