# Alpine.js Core Directives Reference

Quick reference for all Alpine.js directives.

## Data & Initialization

| Directive          | Purpose                                                                        |
| ------------------ | ------------------------------------------------------------------------------ |
| `x-data="{ ... }"` | Define reactive component scope                                                |
| `x-data` (empty)   | Data-less component (access magics only)                                       |
| `x-init="..."`     | Run expression on element init (works without x-data)                          |
| `x-cloak`          | Hide element until Alpine inits (requires `[x-cloak]{display:none!important}`) |
| `x-ignore`         | Skip Alpine processing for element + descendants                               |

`x-data` objects support methods, `get` accessors, and `init()`/`destroy()` lifecycle hooks.

## Rendering

```html
<!-- Text content (innerText) -->
<span x-text="message"></span>

<!-- HTML content (innerHTML) — trusted content only, XSS risk -->
<span x-html="richContent"></span>

<!-- Conditional: toggles display:none (keeps DOM, supports x-transition) -->
<div x-show="open">...</div>

<!-- Conditional: adds/removes DOM (must use <template>, no x-transition) -->
<template x-if="open"><div>...</div></template>

<!-- Loop (must use <template>, single root child) -->
<template x-for="item in items" :key="item.id">
  <li x-text="item.name"></li>
</template>

<!-- Loop with index -->
<template x-for="(item, index) in items">...</template>

<!-- Range loop -->
<template x-for="i in 10">...</template>
```

## Attribute Binding

```html
<!-- Shorthand : syntax -->
<img :src="imageUrl" :alt="altText">

<!-- Class binding (merges with existing classes) -->
<div :class="{ 'hidden': !show, 'active': isActive }">
<div :class="open ? 'opacity-100' : 'opacity-0'">

<!-- Style binding (merges with existing styles) -->
<div :style="{ color: textColor, display: 'flex' }">

<!-- Bind directive bundle -->
<button x-bind="myBindings">
```

## Event Handling

```html
<!-- Shorthand @ syntax -->
<button @click="open = !open">
<button @click="handleClick($event)">

<!-- Modifiers -->
<form @submit.prevent="save()">
<div @click.stop="...">
<div @click.outside="open = false">
<div @keyup.enter="submit()">
<div @keyup.shift.enter="submitAndClose()">
<input @input.debounce.300ms="search($event.target.value)">
<div @scroll.window.throttle.200ms="onScroll()">
<button @click.once="init()">
<div @click.self="...">           <!-- only if target is this element -->
<div @scroll.passive="...">       <!-- non-blocking scroll -->
<div @click.window="...">         <!-- listen on window -->
<div @click.document="...">       <!-- listen on document -->
<div @custom-event.camel="...">   <!-- listen for customEvent -->
```

## Two-Way Binding

```html
<input x-model="name">
<input x-model.lazy="name">           <!-- update on blur -->
<input x-model.number="count">        <!-- cast to number -->
<input x-model.debounce.500ms="query"> <!-- debounced -->
<input x-model.throttle="query">
<input x-model.fill="name">           <!-- fill from value attr -->
```

## Other Directives

```html
<!-- DOM reference -->
<input x-ref="nameInput">
<button @click="$refs.nameInput.focus()">

<!-- Reactive side effect (auto-tracks dependencies, re-runs on change) -->
<div x-effect="console.log(count)">

<!-- Teleport to another DOM location -->
<template x-teleport="body"><div class="modal">...</div></template>

<!-- Expose property for parent x-model binding -->
<div x-modelable="innerValue" x-model="outerValue">

<!-- Scoped unique IDs -->
<div x-id="['input']">
  <label :for="$id('input')">Name</label>
  <input :id="$id('input')">
</div>
```
