Getting Started
Widget
A drop-in React component that adds cross-chain bridging and swapping to your application
The Superbridge Widget is a drop-in React component that adds cross-chain bridging and swapping to your application.
Installation
npm install @superbridge/widgetreact >= 19 and react-dom >= 19 are the only peer dependencies — everything else, including wallet support for every ecosystem, comes with the widget.
Quick start
import { Widget } from "@superbridge/widget";
import "@superbridge/widget/styles.css";
function App() {
return <Widget />;
}That is a complete integration. The widget finds your Rollie from the domain it's running on, loads its chain set, manages wallet connections, and stores the user's settings.
If your framework server-renders, it needs two small accommodations — the stylesheet in the document head and a client-only mount. Integration has the exact setup for Next.js, Vite, TanStack Start, React Router and Astro.
The stylesheet is scoped to the widget, so none of its rules can match your markup. Link it before your own stylesheet anyway — it declares theme variables globally, and yours should win. See Embedding.
There is one component. Whether the widget handles wallets or your app does, you render <Widget /> and pass props.
Props
Every prop is optional. The full set is typed by WidgetProps — your editor will autocomplete and document them inline.
<Widget
// Data
apiUrl="https://api.superbridge.app"
localDevelopmentApiKey={import.meta.env.VITE_WIDGET_DEV_KEY}
// Wallets
walletControl={{ evm: { connect: () => openMyWalletModal() } }}
walletConfig={{ walletConnectProjectId, app: { name: "My App" } }}
// Chrome
chrome={{ settings: false }}
// Appearance
theme={{ cssVariables, motion, textAnimation }}
portalTarget={element}
// Settings
preferences={{ currency: "GBP" }}
defaultPreferences={{ slippage: 1 }}
onPreferencesChange={({ next, changes }) => {}}
// The current transfer
form={{ to: { chainUid: MY_CHAIN } }}
defaultForm={{ amount: "100" }}
onFormChange={({ next, changes }) => {}}
// Behaviour
controls={{ keyboardShortcuts: true }}
onEvent={(event) => analytics.track(event)}
/>Data
| Prop | Type | Description |
|---|---|---|
apiUrl | string | Override the Superbridge API base URL. Defaults to production. |
localDevelopmentApiKey | string | Dev-only key for use on localhost. See Local development. |
Which chains your Rollie offers is configured in the Rollie dashboard, not here. The widget fetches them on mount, showing a loading state while it does.
Wallets
| Prop | Type | Description |
|---|---|---|
walletControl | WalletControl | Ecosystems your app handles wallet connection for. See Wallets. |
walletConfig | WalletConfig | Your WalletConnect project and app identity, for the EVM connectors the widget installs. Not inherited from your Rollie — see Wallets. |
Chrome
| Prop | Type | Description |
|---|---|---|
chrome.settings | boolean | Show the settings button in the widget header. Default true. Hiding it takes currency, language and slippage away from your users. |
chrome.activity | boolean | Show the activity button in the widget header. Default true. |
Appearance
| Prop | Type | Description |
|---|---|---|
theme.cssVariables | WidgetCssVariables | Colors, fonts, radius and per-shape tokens. See Theming. |
theme.motion | MotionProps | Per-element hover/tap/open transitions. |
theme.textAnimation | AnimatedNumberComponent | Custom component used to render every animated number. Must accept { value, format?, className? }. Defaults to a plain formatted span — drop in a flow / scramble / count renderer to animate. |
portalTarget | HTMLElement | Render modals into this element instead of an internal portal, which also makes them cover the page rather than the widget. Must carry the .sb-widget class. See Embedding. |
containedLayout | boolean | Drop the card surface and padding around the form body so the from/to selector and amount input sit flush with the header controls, and wrap the widget in your own container instead. Header, routes and modals are unchanged. Default false. |
Settings and transfer state
| Prop | Type | Description |
|---|---|---|
preferences / defaultPreferences / onPreferencesChange | see State | Durable settings: language, currency, slippage, testnets. |
form / defaultForm / onFormChange | see State | The current transfer: from, to, amount, recipient. |
Behaviour
| Prop | Type | Description |
|---|---|---|
controls.keyboardShortcuts | boolean | Shortcuts like f to open the from-token selector. Default false. |
onEvent | (event: WidgetEvent) => void | Analytics events. See State for when to use this rather than the change handlers. |
Layout
The widget renders at its natural height and fills the width of its container, up to 540px, centring itself in anything wider. Page height and vertical rhythm are yours:
<div className="mx-auto max-w-lg py-24">
<Widget />
</div>Where its modals open is the other half of embedding it — inside the widget's own box by default, over the whole page if you hand it a portalTarget. See Embedding.
Presetting a transfer
Seed the tokens and amount the widget starts on. The user can change any of it afterwards.
<Widget
defaultForm={{
from: { chainKey: "base", tokenAddress: USDC_BASE },
to: { chainKey: "arbitrum", tokenAddress: USDC_ARB },
amount: "100",
}}
/>To keep a value fixed rather than merely preset — always bridging into your own chain, say — control it instead. See State.