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 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 instead.
Required Configuration
The only required field is integrator, which identifies your project in LI.FI analytics:
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 |
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:
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:
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 |
fee, referrer, order, and slippage are not available in sdkConfig.routeOptions. Use the top-level feeConfig, referrer, routePriority, and slippage config fields instead.
Allow/Deny Lists
Filter which chains, tokens, bridges, and exchanges are available:
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
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 |
The walletConfig.useExternalWalletManagement field is set automatically when you pass onConnect to the component. You do not need to set it manually.
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
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:
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.