Documentation Index
Fetch the complete documentation index at: https://docs.li.fi/llms.txt
Use this file to discover all available pages before exploring further.
Widget Light provides a typed event system that lets you react to user interactions, route execution progress, wallet changes, and more. Events are forwarded from the widget iframe to your host application via postMessage.
Subscribing to Events
Use the useWidgetLightEvents() hook to get the event emitter, then subscribe with on and unsubscribe with off:
import {
useWidgetLightEvents,
WidgetLightEvent,
} from '@lifi/widget-light'
import { useEffect } from 'react'
function TransactionTracker() {
const events = useWidgetLightEvents()
useEffect(() => {
const onCompleted = (data: unknown) => {
console.log('Route completed:', data)
}
events.on(WidgetLightEvent.RouteExecutionCompleted, onCompleted)
return () => {
events.off(WidgetLightEvent.RouteExecutionCompleted, onCompleted)
}
}, [events])
return null
}
Key Details
-
Module-level singleton — the event bus is a module-level singleton, so
useWidgetLightEvents() can be called from any component. It does not need to be co-located with <LiFiWidgetLight> and does not require any provider wrapping.
-
Subscription-tracked forwarding — events are only forwarded from the iframe when at least one host-side listener is subscribed. When you call
events.on(eventName, handler), the host sends a WIDGET_EVENT_SUBSCRIBE message to the iframe. When the last listener for an event is removed, the host sends WIDGET_EVENT_UNSUBSCRIBE. This avoids unnecessary postMessage traffic.
-
Stable reference — the emitter returned by
useWidgetLightEvents() is a stable module-level object. You do not need to memoize it or add it to dependency arrays (though it is safe to do so).
Tracking Route Execution
A common use case is tracking the lifecycle of a swap or bridge route:
import {
useWidgetLightEvents,
WidgetLightEvent,
type WidgetLightRouteExecutionUpdate,
} from '@lifi/widget-light'
import { useEffect } from 'react'
function RouteTracker() {
const events = useWidgetLightEvents()
useEffect(() => {
const onStart = (data: unknown) => {
console.log('Route started:', data)
}
const onUpdate = (data: WidgetLightRouteExecutionUpdate) => {
console.log('Step updated:', data.route, data.action)
}
const onComplete = (data: unknown) => {
console.log('Route completed:', data)
}
const onFail = (data: WidgetLightRouteExecutionUpdate) => {
console.error('Route failed:', data.route, data.action)
}
events.on(WidgetLightEvent.RouteExecutionStarted, onStart)
events.on(WidgetLightEvent.RouteExecutionUpdated, onUpdate)
events.on(WidgetLightEvent.RouteExecutionCompleted, onComplete)
events.on(WidgetLightEvent.RouteExecutionFailed, onFail)
return () => {
events.off(WidgetLightEvent.RouteExecutionStarted, onStart)
events.off(WidgetLightEvent.RouteExecutionUpdated, onUpdate)
events.off(WidgetLightEvent.RouteExecutionCompleted, onComplete)
events.off(WidgetLightEvent.RouteExecutionFailed, onFail)
}
}, [events])
return null
}
Event Reference
Route Execution Events
| Event | Payload Type | Description |
|---|
RouteExecutionStarted | unknown | A route has started executing |
RouteExecutionUpdated | WidgetLightRouteExecutionUpdate | Step progress update (contains route and action) |
RouteExecutionCompleted | unknown | Route completed successfully |
RouteExecutionFailed | WidgetLightRouteExecutionUpdate | Route execution failed (contains route and action) |
RouteSelected | WidgetLightRouteSelected | User selected a route (contains route and routes array) |
RouteHighValueLoss | WidgetLightRouteHighValueLoss | High value loss detected on a route |
| Event | Payload Type | Description |
|---|
SourceChainTokenSelected | WidgetLightChainTokenSelected | Source chain/token changed (contains chainId and tokenAddress) |
DestinationChainTokenSelected | WidgetLightChainTokenSelected | Destination chain/token changed (contains chainId and tokenAddress) |
FormFieldChanged | WidgetLightFormFieldChanged | Any form field changed (contains fieldName, newValue, oldValue) |
TokenSearch | WidgetLightTokenSearch | User searched for a token (contains value and tokens) |
Wallet Events
| Event | Payload Type | Description |
|---|
WalletConnected | WidgetLightWalletConnected | Wallet connected (contains address, chainId, chainType, connectorId, connectorName) |
WalletDisconnected | WidgetLightWalletDisconnected | Wallet disconnected (contains chainType and optional address, chainId, connectorId, connectorName) |
UI Events
| Event | Payload Type | Description |
|---|
PageEntered | string | User navigated to a page (page name as string) |
WidgetExpanded | boolean | Widget expanded or collapsed (drawer variant) |
SendToWalletToggled | boolean | Send-to-wallet toggle changed |
AvailableRoutes | unknown[] | Routes have been fetched and are available |
ContactSupport | WidgetLightContactSupport | User clicked contact support (contains optional supportId) |
Settings and Preferences Events
| Event | Payload Type | Description |
|---|
SettingUpdated | WidgetLightSettingUpdated | User changed a setting (contains setting, newValue, oldValue, newSettings, oldSettings) |
ChainPinned | WidgetLightChainPinned | Chain pinned or unpinned (contains chainId and pinned) |
LowAddressActivityConfirmed | WidgetLightLowAddressActivityConfirmed | Low activity address confirmed (contains address and chainId) |
Payload Types
All payload types are exported from @lifi/widget-light:
import type {
WidgetLightRouteExecutionUpdate,
WidgetLightRouteSelected,
WidgetLightRouteHighValueLoss,
WidgetLightChainTokenSelected,
WidgetLightFormFieldChanged,
WidgetLightWalletConnected,
WidgetLightWalletDisconnected,
WidgetLightContactSupport,
WidgetLightSettingUpdated,
WidgetLightChainPinned,
WidgetLightTokenSearch,
WidgetLightLowAddressActivityConfirmed,
} from '@lifi/widget-light'
Route-carrying payloads (WidgetLightRouteExecutionUpdate, WidgetLightRouteSelected) use unknown for the route field because the full route type from @lifi/sdk is not available in Widget Light’s zero-dependency type system. Cast to your local @lifi/sdk types if you need typed access to route properties.
All event names are available as the WidgetLightEvent enum:
import { WidgetLightEvent } from '@lifi/widget-light'
// Use enum values for type-safe event names
events.on(WidgetLightEvent.RouteExecutionCompleted, handler)
// Or use string literals directly
events.on('routeExecutionCompleted', handler)
| Enum Member | String Value |
|---|
WidgetLightEvent.AvailableRoutes | 'availableRoutes' |
WidgetLightEvent.ChainPinned | 'chainPinned' |
WidgetLightEvent.ContactSupport | 'contactSupport' |
WidgetLightEvent.DestinationChainTokenSelected | 'destinationChainTokenSelected' |
WidgetLightEvent.FormFieldChanged | 'formFieldChanged' |
WidgetLightEvent.LowAddressActivityConfirmed | 'lowAddressActivityConfirmed' |
WidgetLightEvent.PageEntered | 'pageEntered' |
WidgetLightEvent.RouteExecutionCompleted | 'routeExecutionCompleted' |
WidgetLightEvent.RouteExecutionFailed | 'routeExecutionFailed' |
WidgetLightEvent.RouteExecutionStarted | 'routeExecutionStarted' |
WidgetLightEvent.RouteExecutionUpdated | 'routeExecutionUpdated' |
WidgetLightEvent.RouteHighValueLoss | 'routeHighValueLoss' |
WidgetLightEvent.RouteSelected | 'routeSelected' |
WidgetLightEvent.SendToWalletToggled | 'sendToWalletToggled' |
WidgetLightEvent.SettingUpdated | 'settingUpdated' |
WidgetLightEvent.SourceChainTokenSelected | 'sourceChainTokenSelected' |
WidgetLightEvent.TokenSearch | 'tokenSearch' |
WidgetLightEvent.WidgetExpanded | 'widgetExpanded' |
WidgetLightEvent.WalletConnected | 'walletConnected' |
WidgetLightEvent.WalletDisconnected | 'walletDisconnected' |