x-data Directive

The starting point of every Alpine component. Define reactive state here.

What is x-data?

x-data declares a new Alpine component scope. It expects a JavaScript object (or a function returning an object) that will become reactive. All Alpine directives inside this element can access its properties. Every interactive component must have an x-data attribute at its root.

💡 Tip

Think of x-data as the data() function in Vue – it holds your component’s state.

When to Use

Use x-data on any element that needs interactive state. A dropdown, modal, counter, or tab component must have x-data at its root. You can have multiple independent x-data components on the same page – they won't interfere with each other.

Basic Usage

Code
<div x-data="{ open: false }">
  <button @click="open = !open">Toggle</button>
  <div x-show="open">This content toggles!</div>
</div>

When open changes, x-show updates automatically because Alpine's reactivity system tracks the dependency.

Using Functions and init()

For more complex logic, you can define x-data as a function. The function runs once when the component initialises, and you can include an init() method that is called automatically.

Code
<div x-data="{
  init() {
    this.count = 0;
    console.log('Component ready');
  },
  count: 0
}">
  <button @click="count++">Increment</button>
  <span x-text="count"></span>
</div>

Reusable Data with Alpine.data()

For components used multiple times, register a global data factory using Alpine.data(). This keeps your code DRY and allows parameters.

Code
<div x-data="dropdown">
  <button @click="toggle">Open</button>
  <div x-show="open">...</div>
</div>
<script>
  document.addEventListener('alpine:init', () => {
    Alpine.data('dropdown', (initial = false) => ({
      open: initial,
      toggle() { this.open = !this.open }
    }))
  })
</script>

Best Practices

  • Keep the data object small – extract large logic into Alpine.data().
  • Use init() for setup (like fetching data).
  • One x-data per component. Nesting is allowed but keep it understandable.
  • Always use x-data as the root attribute; don’t put it on a <template> tag unless wrapping with x-if.
Can I have multiple x‑data components on the same page?

Yes! Each one creates its own independent reactive scope. They do not share state unless you use $store.

What’s the difference between inline object and Alpine.data()?

Inline is fine for one‑off components. Alpine.data() is reusable, testable, and can accept parameters. It also separates your logic from the markup.

Can I use this inside x-data to reference the current element?

You don't need this if you use the object syntax; the properties are accessed directly. Inside Alpine.data(), this works as expected referring to the data proxy.

Live Counter Example

⚠️ Warning

Don’t use x-data on a <template> tag unless it’s wrapped with x-if correctly – the template tag is not rendered, so the data scope won't be attached.

Helpful? Share this page!↑ Back to top