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.
Mode
Modes allow you to present different workflows for your users.
type WidgetMode = 'default' | 'split' | 'custom' | 'refuel';
Default Mode
The default mode provides the standard functionality to bridge and swap in a unified view.
const widgetConfig: WidgetConfig = {
mode: 'default', // This is the default
};
Split Mode
The split mode separates mental models and provides different views for bridging and swapping experiences with tabs on the main page.
const widgetConfig: WidgetConfig = {
mode: 'split',
};
Split Mode Options
For mode: 'split', the modeOptions configuration controls whether to show both “Swap” and “Bridge” tabs or a single interface:
- Default (no options): Shows both “Bridge” and “Swap” tabs
split: 'bridge': Shows only bridge interface (no tabs)
split: 'swap': Shows only swap interface (no tabs)
split: { defaultTab: 'bridge' } or split: { defaultTab: 'swap' }: Shows both tabs with the specified default tab selected
// Default - shows both tabs
const tabsConfig: WidgetConfig = {
mode: 'split',
};
// Pure bridge interface
const bridgeConfig: WidgetConfig = {
mode: 'split',
modeOptions: {
split: 'bridge',
},
};
// Pure swap interface
const swapConfig: WidgetConfig = {
mode: 'split',
modeOptions: {
split: 'swap',
},
};
// Both tabs with swap as default
const tabsSwapDefaultConfig: WidgetConfig = {
mode: 'split',
modeOptions: {
split: { defaultTab: 'swap' },
},
};
Custom Mode
The custom mode offers a different look, allowing you to show custom components and build complete new flows including NFT Checkout and Deposit.
type CustomMode = 'checkout' | 'deposit';
Checkout Flow
For NFT or product checkout flows:
const widgetConfig: WidgetConfig = {
mode: 'custom',
modeOptions: {
custom: { type: 'checkout' },
},
contractCalls: [...], // Your contract calls
contractComponent: <YourCheckoutComponent />,
contractTool: {
name: 'Your Protocol',
logoURI: 'https://your-protocol.com/logo.png',
},
};
Deposit Flow
For protocol deposit flows:
import { ChainType, LiFiWidget, WidgetConfig } from '@lifi/widget';
const widgetConfig: WidgetConfig = {
mode: 'custom',
modeOptions: {
custom: { type: 'deposit' },
},
toAddress: {
name: 'Protocol Vault',
address: '0x...',
chainType: ChainType.EVM,
logoURI: 'https://your-protocol.com/logo.png',
},
disabledUI: { toAddress: true },
hiddenUI: { appearance: true, language: true },
showSingleRoute: true,
contractComponent: <YourDepositCard />,
contractTool: {
name: 'Your Protocol',
logoURI: 'https://your-protocol.com/logo.png',
},
};
See the complete Deposit Flow example.
Refuel Mode
The refuel mode is optimized for gas refueling operations, helping users get native tokens on destination chains.
const widgetConfig: WidgetConfig = {
mode: 'refuel',
};
ModeOptions Interface
type SplitMode = 'bridge' | 'swap'
type SplitModeOptions = {
defaultTab: SplitMode
}
type CustomMode = 'checkout' | 'deposit'
interface ModeOptions {
// Options for 'split' mode
// Pass a string for single-mode (no tabs), or an object for tabs with a default
split?: SplitMode | SplitModeOptions
// Options for 'custom' mode
custom?: { type: CustomMode }
}
Variant
Variants provide a way to optimize the presentational style of the Widget for the space available in your application.
type WidgetVariant = 'compact' | 'wide' | 'drawer';
Compact Variant
The compact variant is a great choice when you have limited space on a page or are dealing with smaller screen sizes. It has everything you need to bridge and swap in a compact view and allows you to integrate the widget wherever you want on your web app’s page.
const widgetConfig: WidgetConfig = {
variant: 'compact', // This is the default
};
Wide Variant
The wide variant allows you to take advantage of bigger page and screen sizes where you might have more available screen real estate. It provides a more comprehensive overview of available routes, displayed in a sidebar with slick animation.
const widgetConfig: WidgetConfig = {
variant: 'wide',
};
The wide variant shows a chain sidebar by default. To hide it, set chainSidebar to true in hiddenUI:
const widgetConfig: WidgetConfig = {
variant: 'wide',
hiddenUI: {
chainSidebar: true,
},
};
Drawer Variant
The drawer variant allows you to show or hide the Widget based on user interaction. It can fit nicely on the page’s side and has the same layout as the compact variant.
const widgetConfig: WidgetConfig = {
variant: 'drawer',
};
Controlling the Drawer
The drawer doesn’t have a pre-built button to open and close it. To control the drawer, create and assign a ref to the widget:
import { useRef } from 'react';
import { LiFiWidget, WidgetDrawer, WidgetConfig } from '@lifi/widget';
export const WidgetPage = () => {
const drawerRef = useRef<WidgetDrawer>(null);
const toggleWidget = () => {
drawerRef.current?.toggleDrawer();
};
const openWidget = () => {
drawerRef.current?.openDrawer();
};
const closeWidget = () => {
drawerRef.current?.closeDrawer();
};
const isWidgetOpen = () => {
return drawerRef.current?.isOpen();
};
return (
<div>
<button onClick={toggleWidget}>Toggle Widget</button>
<button onClick={openWidget}>Open Widget</button>
<button onClick={closeWidget}>Close Widget</button>
<LiFiWidget
ref={drawerRef}
config={{
variant: 'drawer',
}}
integrator="drawer-example"
/>
</div>
);
};
interface WidgetDrawer {
isOpen(): boolean // Check if drawer is open
toggleDrawer(): void // Toggle drawer open/closed
openDrawer(): void // Open the drawer
closeDrawer(): void // Close the drawer
}
Controlled Drawer
You can also control the drawer state externally using the open and onClose props:
import { useState } from 'react';
import { LiFiWidget, WidgetConfig } from '@lifi/widget';
export const WidgetPage = () => {
const [isOpen, setIsOpen] = useState(false);
return (
<div>
<button onClick={() => setIsOpen(true)}>Open Widget</button>
<LiFiWidget
open={isOpen}
onClose={() => setIsOpen(false)}
config={{
variant: 'drawer',
}}
integrator="controlled-drawer-example"
/>
</div>
);
};