> ## 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 API Reference

> Component and hook API reference for @lifi/widget-light

Complete API reference for all exports from `@lifi/widget-light`.

## `<LiFiWidgetLight>`

The main component that renders the widget inside an iframe and manages the postMessage bridge.

```tsx theme={"system"}
import { LiFiWidgetLight } from '@lifi/widget-light'
```

### Props

| Prop           | Type                                 | Required | Default                  | Description                                                                              |
| -------------- | ------------------------------------ | -------- | ------------------------ | ---------------------------------------------------------------------------------------- |
| `src`          | `string`                             | No       | `'https://widget.li.fi'` | URL of the hosted widget iframe                                                          |
| `config`       | `WidgetLightConfig`                  | Yes      | --                       | JSON-serializable widget configuration ([reference](/widget/widget-light-configuration)) |
| `handlers`     | `IframeEcosystemHandler[]`           | No       | `[]`                     | Ecosystem handlers for wallet/RPC bridging                                               |
| `iframeOrigin` | `string`                             | No       | Derived from `src`       | Restrict `postMessage` to this origin                                                    |
| `autoResize`   | `boolean`                            | No       | `false`                  | When `true`, iframe height auto-adjusts to match content                                 |
| `onConnect`    | `(args?: ConnectWalletArgs) => void` | No       | --                       | Called when the widget requests a wallet connection                                      |
| `style`        | `CSSProperties`                      | No       | --                       | Inline styles for the iframe element                                                     |
| `className`    | `string`                             | No       | --                       | CSS class for the iframe element                                                         |
| `title`        | `string`                             | No       | `'LI.FI Widget'`         | Accessible title for the iframe                                                          |

### Example

```tsx theme={"system"}
<LiFiWidgetLight
  config={{ integrator: 'my-app', variant: 'wide' }}
  handlers={[ethHandler, solHandler]}
  autoResize
  style={{ width: 392, borderRadius: 16 }}
/>
```

<Note>
  Only one `<LiFiWidgetLight>` instance per page is supported. The event bus and guest bridge are module-level singletons.
</Note>

## `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.

```tsx theme={"system"}
import { useWidgetLightHost } from '@lifi/widget-light'
```

### Options

| Option         | Type                                 | Required | Default | Description                                  |
| -------------- | ------------------------------------ | -------- | ------- | -------------------------------------------- |
| `config`       | `WidgetLightConfig`                  | Yes      | --      | Widget configuration                         |
| `handlers`     | `IframeEcosystemHandler[]`           | No       | `[]`    | Ecosystem handlers                           |
| `iframeOrigin` | `string`                             | No       | `'*'`   | Expected iframe origin for message filtering |
| `autoResize`   | `boolean`                            | No       | `false` | Enable auto-resize via RESIZE messages       |
| `onConnect`    | `(args?: ConnectWalletArgs) => void` | No       | --      | External wallet connect callback             |

### Return Value

| Field       | Type                                   | Description                              |
| ----------- | -------------------------------------- | ---------------------------------------- |
| `iframeRef` | `RefObject<HTMLIFrameElement \| null>` | Ref to attach to your `<iframe>` element |

### Example

```tsx theme={"system"}
import { useWidgetLightHost } from '@lifi/widget-light'
import { useEthereumIframeHandler } from '@lifi/widget-light/ethereum'
import { useMemo } from 'react'

function CustomIframeSetup() {
  const ethHandler = useEthereumIframeHandler()
  const handlers = useMemo(() => [ethHandler], [ethHandler])

  const { iframeRef } = useWidgetLightHost({
    config: { integrator: 'my-app', fromChain: 1, toChain: 137 },
    handlers,
    iframeOrigin: 'https://widget.li.fi',
    autoResize: true,
  })

  return (
    <iframe
      ref={iframeRef}
      src="https://widget.li.fi"
      title="LI.FI Widget"
      style={{ border: 'none', width: 392, height: 640 }}
      allow="clipboard-write"
    />
  )
}
```

## `useWidgetLightEvents()`

Returns a typed event emitter for subscribing to widget events. Can be called from any component -- no provider wrapping needed.

```tsx theme={"system"}
import { useWidgetLightEvents } from '@lifi/widget-light'
```

### Return Value

```tsx theme={"system"}
interface WidgetLightEventEmitter {
  on<E extends keyof WidgetLightEvents>(
    event: E,
    handler: (data: WidgetLightEvents[E]) => void
  ): void
  off<E extends keyof WidgetLightEvents>(
    event: E,
    handler: (data: WidgetLightEvents[E]) => void
  ): void
}
```

### Example

```tsx theme={"system"}
const events = useWidgetLightEvents()

useEffect(() => {
  const handler = (data: WidgetLightChainTokenSelected) => {
    console.log('Token selected:', data.chainId, data.tokenAddress)
  }
  events.on(WidgetLightEvent.SourceChainTokenSelected, handler)
  return () => events.off(WidgetLightEvent.SourceChainTokenSelected, handler)
}, [events])
```

See [Widget Light Events](/widget/widget-light-events) for the full event reference.

## 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](/widget/widget-light-configuration) for the full reference.

```tsx theme={"system"}
import type { WidgetLightConfig } from '@lifi/widget-light'
```

Required field: `integrator: string`

### `ConnectWalletArgs`

Arguments passed to the `onConnect` callback when the widget requests a wallet connection:

```tsx theme={"system"}
import type { ConnectWalletArgs } from '@lifi/widget-light'
```

| Field       | Type                           | Description                                                      |
| ----------- | ------------------------------ | ---------------------------------------------------------------- |
| `chainId`   | `number \| undefined`          | Target chain ID                                                  |
| `chainType` | `WidgetChainType \| undefined` | Target chain type (`'EVM'`, `'SVM'`, `'UTXO'`, `'MVM'`, `'TVM'`) |

### `IframeEcosystemHandler`

Interface implemented by all ecosystem handlers:

```tsx theme={"system"}
import type { IframeEcosystemHandler } from '@lifi/widget-light'
```

| Method                               | Type                         | Description                                                      |
| ------------------------------------ | ---------------------------- | ---------------------------------------------------------------- |
| `chainType`                          | `WidgetLightChainType`       | `'EVM' \| 'SVM' \| 'UTXO' \| 'MVM' \| 'TVM'`                     |
| `getInitState()`                     | `EcosystemInitState \| null` | Returns initial wallet state for the INIT handshake              |
| `handleRequest(id, method, params?)` | `Promise<unknown>`           | Handles an RPC request from the iframe                           |
| `subscribe(emit)`                    | `() => void`                 | Subscribes to wallet state changes; returns unsubscribe function |

### `WidgetLightEvent`

Enum of all event names. See [Widget Light Events](/widget/widget-light-events) for values and payload types.

```tsx theme={"system"}
import { WidgetLightEvent } from '@lifi/widget-light'
```

### `WidgetLightChainType`

Chain type discriminator used in the postMessage protocol:

```tsx theme={"system"}
type WidgetLightChainType = 'EVM' | 'SVM' | 'UTXO' | 'MVM' | 'TVM'
```

### `WidgetChainType`

Extended chain type used in configuration (includes TVM):

```tsx theme={"system"}
type WidgetChainType = 'EVM' | 'SVM' | 'MVM' | 'UTXO' | '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 via `postMessage`, 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?

When `autoResize` 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 the `INIT` 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?

The `iframeOrigin` 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

Run them locally:

```bash theme={"system"}
# From the widget repository root
pnpm install
pnpm --filter vite-iframe-wagmi dev
# or
pnpm --filter vite-iframe dev
```
