x-on Directive
Attach event listeners easily. Shorthand @click, @keydown, etc. With powerful modifiers.
What is x-on?
x-on attaches event listeners to DOM elements. The shorthand is @event. It’s the backbone of interactivity in Alpine. You can listen to any native browser event (click, keyup, mouseenter, etc.) and even custom events.
When to Use
Every interactive component needs event handling. Use x-on for button clicks, form submissions, keyboard shortcuts, window resize events, or custom events between components.
Basic Examples
<button x-on:click="alert('Clicked!')">Click</button>
<!-- Shorthand -->
<button @click="open = true">Open</button>
<!-- Prevent form submission -->
<form @submit.prevent="save()">...</form>Modifiers Cheat Sheet
.prevent– callsevent.preventDefault()..stop– callsevent.stopPropagation()..once– listener fires only once..passive– for scroll performance..self– only ifevent.targetis the element itself..window– attach the listener to thewindowobject..document– attach the listener to thedocument..debounce.300ms– debounce the handler by 300ms..throttle.200ms– throttle the handler by 200ms.
Keyboard Modifiers
Alpine makes keyboard events trivial. You can chain modifiers to specify the exact key and system keys.
<input @keyup.enter="search()">
<button @keydown.escape="close()">Close</button>
<button @click.ctrl="doSomething()">Ctrl+Click</button>Available key modifiers: .enter, .tab, .escape, .space, .arrow-up, .arrow-down, .arrow-left, .arrow-right, and system modifiers .ctrl, .shift, .alt, .meta.
Custom Events with $dispatch
You can fire custom events using $dispatch and listen to them in parent components or plain JavaScript.
<!-- Child -->
<button @click="$dispatch('notify', { message: 'Hello' })">Notify</button>
<!-- Parent -->
<div @notify="handle($event.detail.message)">...</div>Can I use x-on on a component root?
Yes, you can place it on the same element as x-data or any child element. The event will bubble up naturally.