Skip to main content

Widget events

The widget does not expose public JavaScript callbacks to react to searches or clicks; instead, it exposes two DOM channels:

  1. CustomEvents emitted on window for the host to subscribe to.
  2. CustomEvents listened to on window, that the host can emit to feed the widget.

The logic lives in widget/src/index-preact.tsx (global events) and widget/src/context/CartContext.tsx (neuroon:cart-update).

Emitted events

EventMechanismDetailWhen it fires
neuroon-theme-changewindow.dispatchEvent{ theme: 'light' | 'dark', containerId?: string }Theme changes (OS auto-detect or widget.setTheme()).
neuroon-preview-readywindow.parent.postMessage{ type: 'neuroon-preview-ready', containerId }The widget mounted inside an iframe (internal use: admin previews). Only sent when window.parent !== window.

Example: react to theme change

window.addEventListener('neuroon-theme-change', (e) => {
console.log('Widget switched to theme', e.detail.theme, 'in', e.detail.containerId)
// E.g. sync your store header theme
document.documentElement.dataset.theme = e.detail.theme
})

Listened events (host → widget)

The widget listens to a single host event: neuroon:cart-update. The listener (widget/src/context/CartContext.tsx:165-191) ignores event.detail entirely: when the event fires, it calls config.cart.onGetCart() to read the cart from your host. Debounced 300 ms; ignored while widget-originated operations are in flight.

The event name is configurable via cart.externalUpdateEvent (default 'neuroon:cart-update').

Contract: dispatch the event with no payload — the widget will call your onGetCart(). Don't put data in event.detail; the current listener doesn't read it.

// Correct — the widget will call config.cart.onGetCart() and read your cart.
window.dispatchEvent(new CustomEvent('neuroon:cart-update'))

Example: WordPress / WooCommerce

jQuery(document.body).on('added_to_cart wc_fragments_refreshed removed_from_cart', () => {
window.dispatchEvent(new CustomEvent('neuroon:cart-update'))
})

The official WordPress plugin already wires this bridge automatically in its inline loader; see Plugins → WordPress.

Example: custom SPA

// Your cart code mutated state — notify the widget.
window.dispatchEvent(new CustomEvent('neuroon:cart-update'))
// The widget will invoke config.cart.onGetCart() to re-read.

Full snippet: listener from the host

<script>
// Theme
window.addEventListener('neuroon-theme-change', (e) => {
console.log('[host] theme:', e.detail.theme)
})

// Your host emits cart-update after any cart mutation
function notifyNeuroonCart() {
window.dispatchEvent(new CustomEvent('neuroon:cart-update'))
}

// Hook for your platform:
// - WooCommerce: jQuery(document.body).on('added_to_cart …', notifyNeuroonCart)
// - Custom: call after your own cart mutation
</script>

What the widget does not expose

Today the widget does not emit these events on window (even though they are declared as callbacks in NeuroonWidgetConfig.callbacks):

  • onSearch, onResultClick, onFilterChange, onConversion, onError.

If you need to react to product clicks, use the tracking endpoint POST /api/widget/track/click or query the server-side logs.

Further reading