diff --git a/apps/portal/src/app/bridge/bridge-widget-script/bridge-widget-dark.png b/apps/portal/src/app/bridge/bridge-widget-script/bridge-widget-dark.png
new file mode 100644
index 00000000000..e670a9610dc
Binary files /dev/null and b/apps/portal/src/app/bridge/bridge-widget-script/bridge-widget-dark.png differ
diff --git a/apps/portal/src/app/bridge/bridge-widget-script/bridge-widget-light.png b/apps/portal/src/app/bridge/bridge-widget-script/bridge-widget-light.png
new file mode 100644
index 00000000000..aa5371887c2
Binary files /dev/null and b/apps/portal/src/app/bridge/bridge-widget-script/bridge-widget-light.png differ
diff --git a/apps/portal/src/app/bridge/bridge-widget-script/page.mdx b/apps/portal/src/app/bridge/bridge-widget-script/page.mdx
new file mode 100644
index 00000000000..27edc9542a4
--- /dev/null
+++ b/apps/portal/src/app/bridge/bridge-widget-script/page.mdx
@@ -0,0 +1,467 @@
+import {
+ Details,
+ createMetadata,
+ DocImage
+} from "@doc";
+import bridgeWidgetDark from "./bridge-widget-dark.png";
+import bridgeWidgetLight from "./bridge-widget-light.png";
+
+
+export const metadata = createMetadata({
+ image: {
+ title: "BridgeWidget Script",
+ icon: "payments",
+ },
+ title: "Bridge Widget",
+ description: "Add a widget to add cross swaps and fiat onramp to your app",
+});
+
+# BridgeWidget Script
+
+The BridgeWidget Script makes it easy to embed cross-chain swaps and fiat onramp UI into your app. Just add a script tag to your HTML and get a fully customizable widget — no build setup required.
+
+## Key Features
+- Cross-chain token swaps across 80+ blockchains
+- Fiat onramp support to buy tokens with credit/debit cards
+- Customizable UI - use prebuilt themes or override with your brand colors
+- Prefill token selections for a smoother user experience
+- Display fiat values in multiple currencies
+- Event callbacks to track user actions (success, error, cancel, disconnect)
+
+
+
+
+
+
+
+
+
+
+## Script Integration
+
+```html
+
+
+
+
+
+
+
+
+```
+
+
+## Options
+
+You can customize theme, currencies, token selections, and more. See the full list of options below
+
+
+
+```ts
+type Options = {
+ clientId: string;
+ theme?: "dark" | "light" | {
+ type: "dark" | "light";
+ accentButtonBg?: string;
+ accentButtonText?: string;
+ accentText?: string;
+ borderColor?: string;
+ connectedButtonBg?: string;
+ connectedButtonBgHover?: string;
+ danger?: string;
+ inputAutofillBg?: string;
+ modalBg?: string;
+ modalOverlayBg?: string;
+ primaryButtonBg?: string;
+ primaryButtonText?: string;
+ primaryText?: string;
+ scrollbarBg?: string;
+ secondaryButtonBg?: string;
+ secondaryButtonHoverBg?: string;
+ secondaryButtonText?: string;
+ secondaryIconColor?: string;
+ secondaryIconHoverBg?: string;
+ secondaryIconHoverColor?: string;
+ secondaryText?: string;
+ selectedTextBg?: string;
+ selectedTextColor: string;
+ separatorLine?: string;
+ skeletonBg: string;
+ success?: string;
+ tertiaryBg?: string;
+ tooltipBg?: string;
+ tooltipText?: string;
+ };
+ showThirdwebBranding?: boolean;
+ currency?: SupportedFiatCurrency;
+ swap?: {
+ className?: string;
+ style?: React.CSSProperties;
+ onSuccess?: (quote: SwapPreparedQuote) => void;
+ onError?: (error: Error, quote: SwapPreparedQuote) => void;
+ onCancel?: (quote: SwapPreparedQuote) => void;
+ onDisconnect?: () => void;
+ persistTokenSelections?: boolean;
+ prefill?: {
+ buyToken?: {
+ tokenAddress?: string;
+ chainId: number;
+ amount?: string;
+ };
+ sellToken?: {
+ tokenAddress?: string;
+ chainId: number;
+ amount?: string;
+ };
+ };
+ };
+ buy: {
+ amount: string;
+ chainId: number;
+ tokenAddress?: string;
+ buttonLabel?: string;
+ onCancel?: (quote: BuyOrOnrampPrepareResult | undefined) => void;
+ onError?: (
+ error: Error,
+ quote: BuyOrOnrampPrepareResult | undefined,
+ ) => void;
+ onSuccess?: (quote: BuyOrOnrampPrepareResult) => void;
+ className?: string;
+ country?: string;
+ presetOptions?: [number, number, number];
+ purchaseData?: PurchaseData;
+ };
+}
+```
+
+
+
+
+
+
+### clientId
+Set your Project's client ID to identify your project. You create a project for free on [thirdweb dashboard](https://thirdweb.com/team)
+
+
+### swap
+The options to configure the "Swap" tab
+
+```ts
+type Swap = {
+ className?: string;
+ style?: React.CSSProperties;
+ onSuccess?: (quote: SwapPreparedQuote) => void;
+ onError?: (error: Error, quote: SwapPreparedQuote) => void;
+ onCancel?: (quote: SwapPreparedQuote) => void;
+ onDisconnect?: () => void;
+ persistTokenSelections?: boolean;
+ prefill?: {
+ buyToken?: {
+ tokenAddress?: string;
+ chainId: number;
+ amount?: string;
+ };
+ sellToken?: {
+ tokenAddress?: string;
+ chainId: number;
+ amount?: string;
+ };
+ };
+ }
+```
+
+
+
+
+You can prefill Buy and/or Sell tokens for the swap tab. If `tokenAddress` is not provided, the native token will be used. Here are some examples:
+
+
+#### Set an ERC20 token as the buy token
+
+```js
+BridgeWidget.render(container, {
+ clientId: "your-thirdweb-client-id",
+ swap: {
+ prefill: {
+ // Base USDC
+ buyToken: {
+ chainId: 8453,
+ tokenAddress: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
+ },
+ },
+ },
+});
+```
+
+#### Set a native token as the sell token
+
+```js
+BridgeWidget.render(container, {
+ clientId: "your-thirdweb-client-id",
+ swap: {
+ prefill: {
+ // Base native token (ETH)
+ sellToken: {
+ chainId: 8453,
+ },
+ },
+ },
+});
+```
+
+#### Set amount and token to Buy by default
+
+```js
+BridgeWidget.render(container, {
+ clientId: "your-thirdweb-client-id",
+ swap: {
+ prefill: {
+ buyToken: {
+ chainId: 8453,
+ amount: "0.1",
+ tokenAddress: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
+ },
+ },
+ },
+});
+```
+
+#### Set both buy and sell tokens by default
+
+```ts
+BridgeWidget.render(container, {
+ clientId: "your-thirdweb-client-id",
+ swap: {
+ prefill: {
+ // Base USDC
+ buyToken: {
+ chainId: 8453,
+ tokenAddress: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
+ },
+ // Polygon native token (POL)
+ sellToken: {
+ chainId: 137,
+ },
+ },
+ },
+});
+```
+
+
+
+
+
+
+Whether to persist the token selections to localStorage so that if the user revisits the widget, the last used tokens are pre-selected.
+
+The last used tokens do not override the tokens specified in the `prefill` option. By default, it is set to `true`.
+
+
+
+
+
+
+Pass a callback to be called when the user cancels the purchase.
+
+
+
+
+
+Pass a callback to be called when the user encounters an error during the purchase.
+
+
+
+
+
+Pass a callback to be called when the user successfully completes the purchase.
+
+
+
+
+
+Apply a custom class name to the "Buy" tab content container.
+
+
+
+
+
+Pass a callback to be called when the user disconnects the active wallet.
+
+
+
+
+
+
+### buy
+
+The options to configure the "Buy" tab UI.
+
+
+```ts
+type Buy = {
+ amount: string; // Required
+ chainId: number; // Required
+ tokenAddress?: string;
+ buttonLabel?: string;
+ onCancel?: (quote: BuyOrOnrampPrepareResult | undefined) => void;
+ onError?: (
+ error: Error,
+ quote: BuyOrOnrampPrepareResult | undefined,
+ ) => void;
+ onSuccess?: (quote: BuyOrOnrampPrepareResult) => void;
+ className?: string;
+ country?: string;
+ presetOptions?: [number, number, number];
+ }
+```
+
+
+
+
+Set the default token amount shown in the "Buy" tab.
+
+
+
+
+
+Specify which chain should be selected in the "Buy" tab.
+
+
+
+
+
+Specify which token should be selected in the "Buy" tab. If not specified, the native token of the selected chain will be selected.
+
+
+
+
+
+Override the label for main action button
+
+
+
+
+
+Pass a callback to be called when the user cancels the purchase.
+
+
+
+
+
+Pass a callback to be called when the user encounters an error during the purchase.
+
+
+
+
+
+Pass a callback to be called when the user successfully completes the purchase.
+
+
+
+
+
+Apply a custom class name to the "Buy" tab content container.
+
+
+
+
+
+The user's ISO 3166 alpha-2 country code. This is used to determine onramp provider support.
+
+
+
+
+
+Preset fiat amounts to display in the UI. Defaults to [5, 10, 20].
+
+
+
+
+
+
+
+
+
+
+### theme
+
+Set the theme for the widget. You can either set it to `"dark"`, `"light"` or overrides some or all the colors by passing an object. By default it set to `"dark"`.
+
+When overriding the colors, you must set the `type` to either `"dark"` or `"light"` so that the widget knows which theme to apply the overrides to.
+
+
+```ts
+type Theme = "dark" | "light" | {
+ type: "dark" | "light"; // required
+ accentButtonBg?: string;
+ accentButtonText?: string;
+ accentText?: string;
+ borderColor?: string;
+ connectedButtonBg?: string;
+ connectedButtonBgHover?: string;
+ danger?: string;
+ inputAutofillBg?: string;
+ modalBg?: string;
+ modalOverlayBg?: string;
+ primaryButtonBg?: string;
+ primaryButtonText?: string;
+ primaryText?: string;
+ scrollbarBg?: string;
+ secondaryButtonBg?: string;
+ secondaryButtonHoverBg?: string;
+ secondaryButtonText?: string;
+ secondaryIconColor?: string;
+ secondaryIconHoverBg?: string;
+ secondaryIconHoverColor?: string;
+ secondaryText?: string;
+ selectedTextBg?: string;
+ selectedTextColor: string;
+ separatorLine?: string;
+ skeletonBg: string;
+ success? : string;
+ tertiaryBg?: string;
+ tooltipBg?: string;
+ tooltipText?: string;
+}
+```
+
+#### Example
+
+```js
+BridgeWidget.render(container, {
+ clientId: "your-thirdweb-client-id",
+ theme: {
+ type: "dark",
+ colors: {
+ modalBg: "black",
+ primaryText: "white",
+ },
+ }
+});
+```
+
+
+### currency
+
+The token amounts fiat values will be displayed in this currency. By default, it is set to `"USD"`.
+
+
+```ts
+type Currency = "USD" | "EUR" | "GBP" | "JPY" | "KRW" | "CNY" | "INR" | "NOK" | "SEK" | "CHF" | "AUD" | "CAD" | "NZD" | "MXN" | "BRL" | "CLP" | "CZK" | "DKK" | "HKD" | "HUF" | "IDR" | "ILS" | "ISK";
+```
+
+
+### showThirdwebBranding
+
+Whether to show thirdweb branding at the bottom of the widget. By default, it is set to `true`.
diff --git a/apps/portal/src/app/bridge/page.mdx b/apps/portal/src/app/bridge/page.mdx
index f1381c3b2a6..7fcd9587974 100644
--- a/apps/portal/src/app/bridge/page.mdx
+++ b/apps/portal/src/app/bridge/page.mdx
@@ -102,17 +102,17 @@ const preparedQuote = await Bridge.Buy.prepare({
- The quickest way to setup Bridge in your React app is with the [`BuyWidget`](/references/typescript/v5/widgets/BuyWidget) component.
-
+ The quickest way to setup Bridge in your React app is with the [`SwapWidget`](/references/typescript/v5/widgets/SwapWidget) component.
+
### Live Playground
-
+
### Installation
Install the thirdweb SDK in your React project:
@@ -127,7 +127,7 @@ const preparedQuote = await Bridge.Buy.prepare({
### Create a Client
- First, create a client file (e.g., `thirdwebClient.ts`) for reuse throughout your app:
+ First, create a client file for reuse throughout your app:
```typescript
// thirdwebClient.ts
@@ -140,7 +140,7 @@ const preparedQuote = await Bridge.Buy.prepare({
### Setup the Provider
- Wrap your application with the ThirdwebProvider:
+ Wrap your application with the `ThirdwebProvider`
```tsx
// app.tsx / _app.tsx
@@ -155,21 +155,17 @@ const preparedQuote = await Bridge.Buy.prepare({
}
```
- ### Buy Widget
+ ### Add Swap Widget
- Use the BuyWidget to let users purchase tokens:
+ Use the SwapWidget to let users swap tokens
```tsx
- import { BuyWidget } from "thirdweb/react";
- import { base } from "thirdweb/chains";
+ import { SwapWidget } from "thirdweb/react";
- function PaymentComponent() {
+ function Example() {
return (
-
);
}
diff --git a/apps/portal/src/app/bridge/sidebar.tsx b/apps/portal/src/app/bridge/sidebar.tsx
index b4eaefbbf7a..287f1ec677d 100644
--- a/apps/portal/src/app/bridge/sidebar.tsx
+++ b/apps/portal/src/app/bridge/sidebar.tsx
@@ -32,6 +32,10 @@ export const sidebar: SideBar = {
href: `${bridgeSlug}/routes`,
name: "Get Routes",
},
+ {
+ href: `${bridgeSlug}/bridge-widget-script`,
+ name: "BridgeWidget Script",
+ },
],
name: "Guides",
},
diff --git a/apps/portal/src/components/Document/Details.tsx b/apps/portal/src/components/Document/Details.tsx
index 9fb6e1b55c3..f5206115301 100644
--- a/apps/portal/src/components/Document/Details.tsx
+++ b/apps/portal/src/components/Document/Details.tsx
@@ -30,7 +30,7 @@ export function Details(props: {
- {props.children}
+
+ {props.children}
+
);
}
diff --git a/apps/portal/src/components/Document/Heading.tsx b/apps/portal/src/components/Document/Heading.tsx
index ffafcd05c11..c04ab9b8a2d 100644
--- a/apps/portal/src/components/Document/Heading.tsx
+++ b/apps/portal/src/components/Document/Heading.tsx
@@ -46,7 +46,7 @@ export function Heading(props: {
case 3: {
return (
diff --git a/apps/portal/src/components/Document/Paragraph.tsx b/apps/portal/src/components/Document/Paragraph.tsx
index a3938c275c5..fc23b9e4144 100644
--- a/apps/portal/src/components/Document/Paragraph.tsx
+++ b/apps/portal/src/components/Document/Paragraph.tsx
@@ -5,6 +5,6 @@ export function Paragraph(props: {
className?: string;
}) {
return (
- {props.children}
+ {props.children}
);
}
diff --git a/apps/portal/src/components/ui/tabs.tsx b/apps/portal/src/components/ui/tabs.tsx
index c083eacdb00..501c8980c2e 100644
--- a/apps/portal/src/components/ui/tabs.tsx
+++ b/apps/portal/src/components/ui/tabs.tsx
@@ -32,7 +32,7 @@ const TabsTrigger = React.forwardRef<
"border-transparent border-b text-muted-foreground ring-offset-700 transition-all",
"hover:text-foreground hover:bg-accent data-[state=active]:text-foreground",
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
- "data-[state=active]:before:opacity-100 before:absolute before:opacity-0 before:border-b before:left-0 before:right-0 before:bottom-[-5px] before:transition-opacity before:duration-300",
+ "data-[state=active]:before:opacity-100 before:absolute before:opacity-0 before:border-b-2 before:border-foreground before:left-0 before:right-0 before:bottom-[-5px] before:transition-opacity before:duration-300",
className,
)}
ref={ref}
diff --git a/packages/thirdweb/src/react/web/ui/Bridge/swap-widget/SwapWidget.tsx b/packages/thirdweb/src/react/web/ui/Bridge/swap-widget/SwapWidget.tsx
index 89bc35afe58..f27e5a800ef 100644
--- a/packages/thirdweb/src/react/web/ui/Bridge/swap-widget/SwapWidget.tsx
+++ b/packages/thirdweb/src/react/web/ui/Bridge/swap-widget/SwapWidget.tsx
@@ -48,7 +48,7 @@ export type SwapWidgetProps = {
*/
client: ThirdwebClient;
/**
- * The prefill Buy and/or Sell tokens for the swap widget. If `tokenAddress` is not provided, the native token will be used
+ * Prefill Buy and/or Sell tokens for the swap widget. If `tokenAddress` is not provided, the native token will be used
*
* @example
*