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