Unify Logo Footer.svg
Unify Applications
Logo
Send Custom Event

Send Custom Event

Logo

4 mins READ

Overview

The sendCustomEvent action broadcasts a named event through the UnifyApps event bus. Any block that has a listener registered for that event name will have its corresponding action chain triggered, with the event's payload available as the event context.

This is the primary mechanism for decoupled component communication. Rather than having Block A directly reference Block B's method (tight coupling), Block A emits an event and Block B listens for it — they can be moved, duplicated, or removed without breaking each other.

Parameters

ParameterTypeRequiredDefaultDescription
eventNamestringRequired (required)The unique event identifier. Must be a non-empty string. Convention: use dot-notation namespacing to avoid collisions across modules — e.g. "orders.statusChanged", "cart.itemAdded". Event names are case-sensitive. The builder provides autocomplete from registered listener names.
payloadobjectOptional (optional){}Arbitrary data passed to all listeners. Each listener accesses it via {{ event.payload }} (or the specific key: {{ event.payload.orderId }}). The payload is deep-cloned before distribution, so mutating it in one listener does not affect others.
bubblesbooleanOptional (optional)trueWhen true, the event propagates from the emitting block's container upward through the component tree, reaching parent containers and the page root. When false, only listeners at the same or child levels receive the event. Set to false to scope an event to a specific container module.

Note: Listening for custom events: To handle a custom event, open the Events panel of the target block, click + Add Event, and choose Custom Event. Enter the same eventName string as the emitter uses. Multiple blocks can listen for the same event — all listeners are triggered concurrently when the event fires.

Event Propagation Model

Custom events follow a simplified DOM-like propagation model:

  1. Emit phase: The event is dispatched from the action's source block.

  2. Capture phase: Not supported — events are not captured on the way down.

  3. Bubble phase: If bubbles: true, the event propagates up the container hierarchy. Listeners at each level are triggered as the event passes through.

Events dispatched from the page level (e.g. from a page onLoad action) reach all blocks on the page, regardless of the bubbles setting.

Use Cases

Decoupled Communication Between Unrelated Blocks

A Filter Panel block and a Data Table block on the same page can communicate via custom events rather than shared page variables. The filter panel emits "filters.applied" with the filter criteria in the payload. The data table listens and re-fetches its data source with the new filters. Neither block needs to know the other's ID.

Triggering Walkthrough Steps

Walkthroughs can be configured to advance to the next step when a named custom event fires. Emit "walkthrough.stepComplete" at the end of an action chain to signal the walkthrough engine to advance, enabling step-completion triggers based on actual user actions rather than just button clicks.

Notifying a Parent Module

When a reusable Module component (like an embedded form or a data card) needs to communicate with its parent page without direct reference, emit a custom event. The parent page listens at the page level and responds — keeping the module self-contained and reusable.

Step-by-Step Usage Guide

  1. Define a naming convention: Choose a dot-notation namespace for your events: "domain.action" (e.g. "checkout.orderPlaced"). Document custom events in the page description or a dedicated comment block so the team can find all listeners and emitters quickly.

  2. Emit the event from a source block: In the action chain of the emitting block, add a Send Custom Event action. Set eventName to your chosen name and populate the payload with any relevant data using bindings.

  3. Register a listener on the target block: Select the target block, open its Events panel, click + Add Event → Custom Event, and enter the same eventName. Add action chains to this listener — they receive {{ event.payload }} as context.

  4. Test in Builder preview: Trigger the emitting action and verify the listener fires in the Dev Tools → Events panel. The panel shows which events were dispatched, their payload, and which listeners received them.

Examples

Emit a filter-applied event with criteria payload

{ "actionType": "sendCustomEvent", "payload": { "eventName": "filters.applied", "payload": { "status": "{{ var_filterStatus }}", "dateFrom": "{{ var_filterDateFrom }}", "dateTo": "{{ var_filterDateTo }}" }, "bubbles": true } }

Signal a walkthrough step completion

{ "actionType": "sendCustomEvent", "payload": { "eventName": "walkthrough.onboarding.step3Complete", "payload": { "userId": "{{ appUser.id }}", "completedAt": "{{ now() }}" } } }

Notify parent page from a reusable module

// Inside an embedded product-card module: { "actionType": "sendCustomEvent", "payload": { "eventName": "productCard.addedToCart", "payload": { "productId": "{{ b_productCard.state.productId }}", "quantity": "{{ b_quantityInput.state.value }}" }, "bubbles": true } } // Parent page listener (on productCard.addedToCart): // → Update cart count variable // → Show success toast