@lifi/widget-light.
<LiFiWidgetLight>
The main component that renders the widget inside an iframe and manages the postMessage bridge.
Props
Example
Only one
<LiFiWidgetLight> instance per page is supported. The event bus and guest bridge are module-level singletons.useWidgetLightHost(options)
Low-level hook that manages the host side of the postMessage bridge. Use this if you need to render your own <iframe> element instead of using the <LiFiWidgetLight> component.
Options
Return Value
Example
useWidgetLightEvents()
Returns a typed event emitter for subscribing to widget events. Can be called from any component — no provider wrapping needed.
Return Value
Example
Types
WidgetLightChainType vs WidgetChainType: Both unions describe ecosystem discriminators and include TVM for Tron. Use WidgetLightChainType for the iframe postMessage protocol (for example IframeEcosystemHandler.chainType). Use WidgetChainType on host-facing config types such as ConnectWalletArgs.chainType, where the hosted widget tells your app which ecosystem to connect. The names differ because protocol-level types and configuration-level types are defined separately in the package.
WidgetLightConfig
The primary configuration type. Must be JSON-serializable. See Configure Widget Light for the full reference.
integrator: string
ConnectWalletArgs
Arguments passed to the onConnect callback when the widget requests a wallet connection:
IframeEcosystemHandler
Interface implemented by all ecosystem handlers:
WidgetLightEvent
Enum of all event names. See Widget Light Events for values and payload types.
WidgetLightChainType
Chain type discriminator used in the postMessage protocol:
WidgetChainType
Extended chain type used in configuration (includes TVM):
FAQ
Can I run multiple widgets on the same page?
No.@lifi/widget-light uses a module-level singleton for the event bus and guest bridge. Only one <LiFiWidgetLight> instance per page is supported.
What URL should I use for src?
The default (https://widget.li.fi) is the production-hosted widget. You do not need to set src at all for most use cases. For testing against a specific version or a self-hosted deployment, pass your custom URL as src.
Why must config be JSON-serializable?
Configuration is sent to the iframe viapostMessage, which uses the structured clone algorithm. React nodes, functions, class instances, and MUI theme objects cannot be cloned. The WidgetLightConfig type only exposes serializable fields (no React nodes, callbacks, or MUI theme objects), so the type system rejects most non-serializable values at compile time. This is enforcement by omission rather than a general serializability check, so still ensure any values you pass are JSON-serializable at runtime.
How does auto-resize work?
WhenautoResize is true, the iframe content uses a ResizeObserver to detect height changes and posts them to the host. The host directly sets iframe.style.height for zero-flicker updates. Set autoResize={false} if you want to control iframe dimensions yourself via CSS.
Do I need to handle reconnection after page refresh?
Wallet state is sent from your app to the iframe on every mount via theINIT handshake. If your wagmi/wallet-adapter handles reconnection (which most do by default), the widget will automatically receive the reconnected state.
How is security handled?
TheiframeOrigin is automatically derived from src (defaults to https://widget.li.fi), so postMessage communication is restricted to the correct origin. Messages from other origins are silently dropped. You only need to set iframeOrigin explicitly if you want to override the derived value.
Where can I find working examples?
The widget repository includes two examples:- vite-iframe-wagmi — Minimal EVM-only integration
- vite-iframe — Full multi-ecosystem setup with events, config reactivity, and external wallet management

