Description: The $dispatch() magic property in AlpineJS allows components to emit custom events. This is a powerful mechanism for enabling decoupled communication between different parts of your application. Other components, whether they are parents, siblings, or even unrelated components listening globally, can react to these events. This promotes modularity by allowing components to signal changes or actions without needing direct knowledge of each other.
$dispatch('eventName', detailObject)
This is the core function for emitting custom events.
'eventName': A string that uniquely identifies your custom event (e.g., 'item-selected', 'notification-show'). Choose descriptive names.detailObject: An optional JavaScript object that serves as the payload for your event. This data can be accessed by any component listening for this event. For example, { itemId: 123, message: 'Hello!' }.By default, events dispatched this way "bubble" up the DOM tree from the dispatching element.
<button @click="$dispatch('user-action', { id: 1, type: 'save' })">Save</button>
@event-name.modifier="handler($event.detail)"
This is Alpine's shorthand syntax (x-on:event-name) for listening to DOM events, including custom ones.
event-name: The name of the custom event you want to listen for (must match the name used in $dispatch precisely, it's case-sensitive)..modifier: Optional modifiers can alter how the event is handled. Common ones include:
.window: Listens for the event on the global window object ( crucial for non-ancestor communication)..document: Listens for the event on the global document object..once: The handler will only be triggered once..prevent: Calls event.preventDefault()..stop: Calls event.stopPropagation().handler($event.detail): The JavaScript expression or component method to execute when the event is caught.
$event: Represents the native browser Event object.$event.detail: This is where the detailObject payload (the second argument to $dispatch) is accessible. This is a standard convention for custom events.<div @user-action.window="handleUserAction($event.detail)">...</div>
.window modifier
When you need a component to listen for an event regardless of its position in the DOM relative to the dispatching component (e.g., sibling components, or components in entirely different DOM trees), the .window modifier is essential. It attaches the event listener to the global window object. Without it, an event dispatched by a component will only bubble up its own DOM ancestor chain and might not be "heard" by components outside that chain.
Using the .window modifier is crucial for global events or when the listening component is not a direct ancestor of the dispatching component.
If Component A dispatches an event, and Component B (which is not an ancestor of A, e.g., a sibling or in a completely different part of the page) needs to react, Component B *must* listen on the window (@my-event.window="handler"). Otherwise, the event will bubble up from Component A and Component B will never "see" it. This is a common point of confusion if you expect events to be globally available by default.
Event detail ($event.detail) is where the payload sent with $dispatch is found.
When you dispatch an event like $dispatch('my-event', { message: 'Hello' }), the data { message: 'Hello' } is not directly available as properties on the $event object itself (e.g., not $event.message). Instead, the entire payload object is nested within $event.detail. So, to access the message in a handler, you would use $event.detail.message. This is part of the Web API standard for CustomEvent.
This example demonstrates communication between two "conceptual" components on the same page. One component (Sender) dispatches a global message, and another (Receiver) listens for this global message and displays it. This showcases notifying a non-ancestor component.
Type a message and click "Send Global Notification". This will dispatch a custom event named 'global-message' with your text.
This area listens for 'global-message' events on the window object. New messages will appear below.