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

# Configure Widget Light

> Configuration reference for @lifi/widget-light

Widget Light configuration is passed as a `WidgetLightConfig` object to the `config` prop of `<LiFiWidgetLight>`. All configuration must be **JSON-serializable** because it is sent to the iframe via `postMessage`.

## JSON-Serializable Constraint

Because configuration crosses the iframe boundary via `postMessage` (which uses the structured clone algorithm), the following are **not supported** in `WidgetLightConfig`:

* React nodes or JSX elements
* Callback functions
* Class instances
* MUI theme objects (`palette`, `colorSchemes`, `shape`, `typography`, `components`)

`WidgetLightConfig` is a curated subset of the full widget config that only exposes serializable fields -- the non-serializable options listed above simply aren't part of the type, so passing them is a TypeScript error. This is enforcement by omission rather than a general serializability guard, so make sure any nested values you do pass are JSON-serializable at runtime.

If you need the full configuration surface including React nodes and MUI theming, use the [full widget](/widget/overview) instead.

## Required Configuration

The only required field is `integrator`, which identifies your project in LI.FI analytics:

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

const config: WidgetLightConfig = {
  integrator: 'your-project-name',
}
```

## Configuration Reference

### Layout

| Field         | Type                                           | Description                        |
| ------------- | ---------------------------------------------- | ---------------------------------- |
| `variant`     | `'compact' \| 'wide' \| 'drawer'`              | Widget layout variant              |
| `mode`        | `'default' \| 'split' \| 'custom' \| 'refuel'` | Widget mode                        |
| `modeOptions` | `WidgetModeOptions`                            | Options for split and custom modes |

```tsx theme={"system"}
const config: WidgetLightConfig = {
  integrator: 'my-app',
  variant: 'wide',
  mode: 'split',
  modeOptions: {
    split: { defaultTab: 'bridge' },
  },
}
```

### Appearance

| Field        | Type                            | Description                           |
| ------------ | ------------------------------- | ------------------------------------- |
| `appearance` | `'light' \| 'dark' \| 'system'` | Color scheme preference               |
| `theme`      | `WidgetTheme`                   | CSS-based theme overrides (see below) |

The `theme` object supports CSS properties for specific containers. This is not a MUI theme -- only serializable CSS properties are accepted:

```tsx theme={"system"}
const config: WidgetLightConfig = {
  integrator: 'my-app',
  appearance: 'dark',
  theme: {
    container: {
      border: '1px solid #eaeaea',
      borderRadius: '16px',
    },
    header: {
      background: '#f5f5f5',
    },
    navigation: {
      edge: true,
    },
  },
}
```

**`WidgetTheme` fields:**

| Field                   | Type                 | Description                                 |
| ----------------------- | -------------------- | ------------------------------------------- |
| `container`             | CSS properties       | Styles for the widget container             |
| `routesContainer`       | CSS properties       | Styles for the routes list container        |
| `chainSidebarContainer` | CSS properties       | Styles for the chain sidebar (wide variant) |
| `header`                | CSS properties       | Styles for the widget header                |
| `navigation`            | `{ edge?: boolean }` | Navigation layout options                   |

### Chain and Token Selection

| Field              | Type                | Description                              |
| ------------------ | ------------------- | ---------------------------------------- |
| `fromChain`        | `number`            | Pre-selected source chain ID             |
| `toChain`          | `number`            | Pre-selected destination chain ID        |
| `fromToken`        | `string`            | Pre-selected source token address        |
| `toToken`          | `string`            | Pre-selected destination token address   |
| `fromAmount`       | `number \| string`  | Pre-filled source amount                 |
| `toAmount`         | `number \| string`  | Pre-filled destination amount            |
| `minFromAmountUSD` | `number`            | Minimum source amount in USD             |
| `toAddress`        | `WidgetToAddress`   | Pre-filled destination address           |
| `toAddresses`      | `WidgetToAddress[]` | List of selectable destination addresses |
| `formUpdateKey`    | `string`            | Key to force form update                 |

### API and Fees

| Field       | Type              | Description         |
| ----------- | ----------------- | ------------------- |
| `apiKey`    | `string`          | Your LI.FI API key  |
| `feeConfig` | `WidgetFeeConfig` | Fee configuration   |
| `referrer`  | `string`          | Referrer identifier |

**`WidgetFeeConfig` fields:**

| Field               | Type      | Default | Description                   |
| ------------------- | --------- | ------- | ----------------------------- |
| `name`              | `string`  | --      | Display name for the fee      |
| `logoURI`           | `string`  | --      | Logo URL for the fee          |
| `fee`               | `number`  | --      | Fee percentage (0 to 1)       |
| `showFeePercentage` | `boolean` | `false` | Show the fee as a percentage  |
| `showFeeTooltip`    | `boolean` | `false` | Show an informational tooltip |

### Routing

| Field              | Type                                                   | Description                                             |
| ------------------ | ------------------------------------------------------ | ------------------------------------------------------- |
| `routePriority`    | `'RECOMMENDED' \| 'FASTEST' \| 'CHEAPEST' \| 'SAFEST'` | Default route sorting priority                          |
| `slippage`         | `number`                                               | Default slippage tolerance                              |
| `showSingleRoute`  | `boolean`                                              | Show only the recommended route and hide route selector |
| `useRelayerRoutes` | `boolean`                                              | Enable gasless/relayer routes                           |

### SDK Configuration

The `sdkConfig` field controls API and routing behavior:

```tsx theme={"system"}
const config: WidgetLightConfig = {
  integrator: 'my-app',
  sdkConfig: {
    apiUrl: 'https://li.quest/v1',
    routeOptions: {
      maxPriceImpact: 0.4,
      bridges: { allow: ['stargate', 'across'] },
      exchanges: { deny: ['dodo'] },
    },
    rpcUrls: {
      1: ['https://your-eth-rpc.com'],
      137: ['https://your-polygon-rpc.com'],
    },
  },
}
```

**`WidgetSDKConfig` fields:**

| Field                   | Type                       | Description                      |
| ----------------------- | -------------------------- | -------------------------------- |
| `apiUrl`                | `string`                   | Custom LI.FI API URL             |
| `userId`                | `string`                   | User identifier for tracking     |
| `rpcUrls`               | `Record<number, string[]>` | Custom RPC URLs per chain ID     |
| `routeOptions`          | `WidgetRouteOptions`       | Routing options (see below)      |
| `preloadChains`         | `boolean`                  | Preload chain data on init       |
| `chainsRefetchInterval` | `number`                   | Chain data refetch interval (ms) |

**`WidgetRouteOptions` fields:**

| Field                  | Type                         | Description                            |
| ---------------------- | ---------------------------- | -------------------------------------- |
| `maxPriceImpact`       | `number`                     | Maximum acceptable price impact        |
| `allowSwitchChain`     | `boolean`                    | Allow chain switching during execution |
| `allowDestinationCall` | `boolean`                    | Allow destination chain contract calls |
| `bridges`              | `{ allow?, deny?, prefer? }` | Bridge allow/deny/prefer lists         |
| `exchanges`            | `{ allow?, deny?, prefer? }` | Exchange allow/deny/prefer lists       |
| `jitoBundle`           | `boolean`                    | Enable Jito bundle support for Solana  |

<Note>
  `fee`, `referrer`, `order`, and `slippage` are not available in `sdkConfig.routeOptions`. Use the top-level `feeConfig`, `referrer`, `routePriority`, and `slippage` config fields instead.
</Note>

### Allow/Deny Lists

Filter which chains, tokens, bridges, and exchanges are available:

```tsx theme={"system"}
const config: WidgetLightConfig = {
  integrator: 'my-app',
  chains: {
    allow: [1, 137, 42161],          // Only show these chains
    from: { allow: [1, 137] },       // Source chain filter
    to: { deny: [56] },              // Destination chain filter
    types: { allow: ['EVM', 'SVM'] }, // Filter by chain type
  },
  tokens: {
    featured: [{ chainId: 1, address: '0x...', symbol: 'USDC', decimals: 6, name: 'USD Coin' }],
    allow: [{ chainId: 1, address: '0x...' }],
    deny: [{ chainId: 1, address: '0x...' }],
  },
  bridges: {
    allow: ['stargate', 'across'],
  },
  exchanges: {
    deny: ['dodo'],
  },
}
```

### UI Controls

Control which UI elements are visible, disabled, or required. Each option uses an object config where keys are UI element names and values are booleans:

| Field        | Type                     | Description                                          |
| ------------ | ------------------------ | ---------------------------------------------------- |
| `hiddenUI`   | `WidgetHiddenUIConfig`   | UI elements to hide                                  |
| `disabledUI` | `WidgetDisabledUIConfig` | UI elements to disable (visible but not interactive) |
| `requiredUI` | `WidgetRequiredUIConfig` | UI elements that must be filled before proceeding    |
| `defaultUI`  | `WidgetDefaultUI`        | Default UI state overrides                           |

**`hiddenUI` keys:** `appearance`, `drawerCloseButton`, `history`, `language`, `poweredBy`, `toAddress`, `fromToken`, `toToken`, `walletMenu`, `integratorStepDetails`, `reverseTokensButton`, `routeTokenDescription`, `routeCardPriceImpact`, `chainSelect`, `chainSidebar`, `bridgesSettings`, `addressBookConnectedWallets`, `lowAddressActivityConfirmation`, `gasRefuelMessage`, `searchTokenInput`, `insufficientGasMessage`, `contactSupport`, `hideSmallBalances`, `allNetworks`

**`disabledUI` keys:** `fromAmount`, `fromToken`, `toAddress`, `toToken`

**`requiredUI` keys:** `toAddress`, `accountDeployedMessage`

```tsx theme={"system"}
const config: WidgetLightConfig = {
  integrator: 'my-app',
  hiddenUI: { appearance: true, language: true, poweredBy: true },
  disabledUI: { toAddress: true },
  requiredUI: { toAddress: true },
  defaultUI: {
    transactionDetailsExpanded: true,
    navigationHeaderTitleNoWrap: false,
  },
}
```

### Wallet Configuration

| Field                                        | Type                                | Description                           |
| -------------------------------------------- | ----------------------------------- | ------------------------------------- |
| `walletConfig.walletEcosystemsOrder`         | `Record<string, WidgetChainType[]>` | Custom wallet ecosystem ordering      |
| `walletConfig.usePartialWalletManagement`    | `boolean`                           | Enable partial wallet management      |
| `walletConfig.forceInternalWalletManagement` | `boolean`                           | Force the widget's internal wallet UI |

<Note>
  The `walletConfig.useExternalWalletManagement` field is set automatically when you pass `onConnect` to the component. You do not need to set it manually.
</Note>

### Internationalization

| Field               | Type                      | Description                |
| ------------------- | ------------------------- | -------------------------- |
| `languages`         | `WidgetLanguages`         | Language configuration     |
| `languageResources` | `WidgetLanguageResources` | Custom translation strings |

Supported language keys: `en`, `es`, `fr`, `de`, `it`, `pt`, `ja`, `ko`, `zh`, `hi`, `bn`, `th`, `vi`, `tr`, `uk`, `id`, `pl`

```tsx theme={"system"}
const config: WidgetLightConfig = {
  integrator: 'my-app',
  languages: {
    default: 'de',
    allow: ['en', 'de', 'fr'],
  },
}
```

### Miscellaneous

| Field           | Type                                  | Description                                         |
| --------------- | ------------------------------------- | --------------------------------------------------- |
| `buildUrl`      | `boolean`                             | Sync widget state to URL parameters                 |
| `keyPrefix`     | `string`                              | Prefix for local storage keys                       |
| `explorerUrls`  | `Record<number, WidgetExplorerUrl[]>` | Custom block explorer URLs per chain                |
| `poweredBy`     | `'default' \| 'jumper'`               | "Powered by" branding variant                       |
| `routeLabels`   | `WidgetRouteLabelRule[]`              | Custom labels for routes matching specific criteria |
| `contractCalls` | `WidgetContractCall[]`                | Contract calls for the custom mode                  |
| `contractTool`  | `WidgetContractTool`                  | Tool branding for contract calls                    |

## Reactive Config Updates

Configuration is reactive. When you pass a new `config` object, the widget updates in real-time without reloading the iframe:

```tsx theme={"system"}
import { LiFiWidgetLight } from '@lifi/widget-light'
import type { WidgetLightConfig } from '@lifi/widget-light'
import { useMemo, useState } from 'react'

const baseConfig: WidgetLightConfig = {
  integrator: 'my-app',
}

function App() {
  const [variant, setVariant] = useState<'wide' | 'compact'>('wide')

  const widgetConfig = useMemo(
    () => ({ ...baseConfig, variant }),
    [variant]
  )

  return (
    <>
      <button onClick={() => setVariant('compact')}>Compact</button>
      <button onClick={() => setVariant('wide')}>Wide</button>
      <LiFiWidgetLight config={widgetConfig} handlers={handlers} />
    </>
  )
}
```

Config changes are sent to the iframe via the `CONFIG_UPDATE` message after the initial handshake. The widget applies the new configuration without a full reload, preserving any in-progress state.
