Alpine.js
02 / 02

Reusable Components & Effects

Reusable Components & Effects

Alpine.data — Sharing Logic

document.addEventListener('alpine:init', () => {
  Alpine.data('dropdown', () => ({
    open: false,
    toggle() { this.open = !this.open; },
    close() { this.open = false; },
  }));
});
<!-- Reused across as many elements as needed — no copy-pasted inline objects -->
<div x-data="dropdown" @click.outside="close()">
  <button @click="toggle()">Menu</button>
  <div x-show="open">...</div>
</div>

x-effect — Reacting to State Changes

<div x-data="{ count: 0 }">
  <button @click="count++">Increment</button>

  <!-- Re-runs automatically whenever `count` changes — for side effects
       that don't map onto a specific attribute, like persisting to storage -->
  <div x-effect="localStorage.setItem('count', count)"></div>
</div>

When Alpine Fits

Alpine shines for adding scoped interactivity (dropdowns, modals, tabs, inline validation feedback) to an otherwise server-rendered page — Laravel, Rails, Django, or a static site — without pulling in a full SPA framework's build tooling and bundle size for just a handful of small widgets. It's not trying to replace React/Vue for genuinely complex client-side applications with heavy state and routing needs.

Keep your own version of these notes — editable, searchable, and organised by your stack.

Start free