diff --git a/apps/dashboard/src/app/bridge/checkout-widget/CheckoutWidgetEmbed.client.tsx b/apps/dashboard/src/app/bridge/checkout-widget/CheckoutWidgetEmbed.client.tsx
index 3dc69e9c571..57bc6194fab 100644
--- a/apps/dashboard/src/app/bridge/checkout-widget/CheckoutWidgetEmbed.client.tsx
+++ b/apps/dashboard/src/app/bridge/checkout-widget/CheckoutWidgetEmbed.client.tsx
@@ -83,11 +83,16 @@ export function CheckoutWidgetEmbed({
wallets: bridgeWallets,
appMetadata,
}}
- onSuccess={(data) => {
- sendMessageToParent("success", data);
+ onSuccess={() => {
+ sendMessageToParent({
+ source: "checkout-widget",
+ type: "success",
+ });
}}
onError={(error) => {
- sendMessageToParent("error", {
+ sendMessageToParent({
+ source: "checkout-widget",
+ type: "error",
message: error.message,
});
}}
@@ -95,19 +100,9 @@ export function CheckoutWidgetEmbed({
);
}
-function sendMessageToParent(
- type: "success" | "error",
- data: object | undefined,
-) {
+function sendMessageToParent(content: object) {
try {
- window.parent.postMessage(
- {
- source: "checkout-widget",
- type,
- data,
- },
- "*",
- );
+ window.parent.postMessage(content, "*");
} catch (error) {
console.error("Failed to send post message to parent window");
console.error(error);
diff --git a/apps/portal/src/app/bridge/checkout-widget/checkout-widget-dark.jpg b/apps/portal/src/app/bridge/checkout-widget/checkout-widget-dark.jpg
new file mode 100644
index 00000000000..ec1a3b970b6
Binary files /dev/null and b/apps/portal/src/app/bridge/checkout-widget/checkout-widget-dark.jpg differ
diff --git a/apps/portal/src/app/bridge/checkout-widget/checkout-widget.jpg b/apps/portal/src/app/bridge/checkout-widget/checkout-widget.jpg
new file mode 100644
index 00000000000..5ef89ea7a7b
Binary files /dev/null and b/apps/portal/src/app/bridge/checkout-widget/checkout-widget.jpg differ
diff --git a/apps/portal/src/app/bridge/checkout-widget/iframe/iframe-code-preview.tsx b/apps/portal/src/app/bridge/checkout-widget/iframe/iframe-code-preview.tsx
new file mode 100644
index 00000000000..6d80b03a443
--- /dev/null
+++ b/apps/portal/src/app/bridge/checkout-widget/iframe/iframe-code-preview.tsx
@@ -0,0 +1,34 @@
+import { CodeBlock, Tabs, TabsContent, TabsList, TabsTrigger } from "@doc";
+
+export function IframeCodePreview(props: { src: string }) {
+ return (
+
+
+ Code
+ Preview
+
+
+ `}
+ lang="html"
+ />
+
+
+
+
+
+ );
+}
diff --git a/apps/portal/src/app/bridge/checkout-widget/iframe/page.mdx b/apps/portal/src/app/bridge/checkout-widget/iframe/page.mdx
new file mode 100644
index 00000000000..2170305f675
--- /dev/null
+++ b/apps/portal/src/app/bridge/checkout-widget/iframe/page.mdx
@@ -0,0 +1,162 @@
+import {
+ ArticleIconCard,
+ Details,
+ createMetadata,
+ DocImage,
+} from "@doc";
+import { IframeCodePreview } from "./iframe-code-preview";
+import { PlayIcon } from "lucide-react";
+import checkoutWidgetDark from "../checkout-widget-dark.jpg";
+import checkoutWidgetLight from "../checkout-widget.jpg";
+
+export const metadata = createMetadata({
+ image: {
+ title: "Checkout widget iframe",
+ icon: "payments",
+ },
+ title: "Checkout widget iframe",
+ description: "Add a widget to accept crypto and fiat payments in your app using an iframe",
+});
+
+# Checkout widget iframe
+
+The Checkout widget iframe makes it easy to accept crypto and fiat payments in your app. Just add an iframe to your HTML and get a fully customizable checkout widget - no build setup required.
+
+
+
+
+
+
+
+
+## Features
+
+- Accept payments in crypto or fiat (credit/debit cards)
+- Cross-chain payment support across 85+ blockchains
+- Display product information (name, description, image)
+- Dark and light mode support
+- Display fiat values in multiple currencies
+
+## Iframe Integration
+
+The checkout widget requires below minimum parameters to be set:
+
+- `chain` - The chain ID where you want to receive payment (e.g., 8453 for Base)
+- `tokenAddress` (optional) - The token address to accept as payment. If this parameter is not set, payment will be accepted in the native token of the specified chain.
+- `amount` - The amount to charge (as a decimal string, e.g., "0.01")
+- `seller` - The wallet address that will receive the payment
+
+### Example
+
+Accept 0.1 USDC on Base as payment to seller (`0xdd99b75f095d0c4d5112aCe938e4e6ed962fb024`)
+
+
+
+## Try it out
+
+
+
+## Options
+
+You can customize the checkout widget using query parameters as mentioned below.
+
+
+### Theme
+
+By default the widget uses the "dark" theme. You can set the light theme by passing the `theme=light` query parameter.
+
+
+
+
+### Product Information
+
+You can display product information by passing `title`, `description`, and `image` query parameters. Each of these parameters are optional.
+
+Make sure to URI encode the parameters if they contain special characters
+
+
+
+* title: `"Something"`
+* description: `"Description of something goes here"`
+* image: `"https://picsum.photos/600/300"`
+* price: 0.01 ETH on Base
+
+
+
+
+
+
+### Currency
+
+By default the fiat value of the token amounts is displayed in USD. You can change the currency by setting the `currency` query parameter.
+
+
+
+- `USD` - US Dollar (default)
+- `EUR` - Euro
+- `GBP` - British Pound
+- `JPY` - Japanese Yen
+- `KRW` - Korean Won
+- `CNY` - Chinese Yuan
+- `INR` - Indian Rupee
+- `NOK` - Norwegian Krone
+- `SEK` - Swedish Krona
+- `CHF` - Swiss Franc
+- `AUD` - Australian Dollar
+- `CAD` - Canadian Dollar
+- `NZD` - New Zealand Dollar
+- `MXN` - Mexican Peso
+- `BRL` - Brazilian Real
+- `CLP` - Chilean Peso
+- `CZK` - Czech Koruna
+- `DKK` - Danish Krone
+- `HKD` - Hong Kong Dollar
+- `HUF` - Hungarian Forint
+- `IDR` - Indonesian Rupiah
+- `ILS` - Israeli New Sheqel
+- `ISK` - Icelandic Krona
+
+
+
+#### Example
+
+Show fiat values in Euro (EUR) in the widget.
+
+
+
+### thirdweb branding
+
+By default, the widget displays thirdweb branding at the bottom. You can hide this by setting the `showThirdwebBranding` query parameter to `false`.
+
+
+
+## Listening for Events
+
+The checkout widget iframe sends events to the parent window using `postMessage` when a purchase succeeds or fails.
+
+You can listen for these events to handle the purchase result in your application.
+
+```js
+window.addEventListener("message", (event) => {
+
+ // verify that message is from thirdweb checkout widget iframe
+ if (
+ event.origin === "https://thirdweb.com" && event.data.source === "checkout-widget"
+ ) {
+
+ if (event.data.type === "success") {
+ console.log("Purchase successful!");
+ }
+
+ if (event.data.type === "error") {
+ console.error("Purchase failed with error:", event.data.message);
+ }
+ }
+
+});
+```
diff --git a/apps/portal/src/app/bridge/checkout-widget/page.mdx b/apps/portal/src/app/bridge/checkout-widget/page.mdx
new file mode 100644
index 00000000000..5522feb96b2
--- /dev/null
+++ b/apps/portal/src/app/bridge/checkout-widget/page.mdx
@@ -0,0 +1,71 @@
+import {
+ Details,
+ createMetadata,
+ DocImage,
+} from "@doc";
+import { ArticleIconCard } from "@doc";
+import { FrameIcon, PlayIcon } from "lucide-react";
+import { ReactIcon } from "@/icons";
+import checkoutWidgetDark from "./checkout-widget-dark.jpg";
+import checkoutWidgetLight from "./checkout-widget.jpg";
+
+export const metadata = createMetadata({
+ image: {
+ title: "Checkout widget",
+ icon: "payments",
+ },
+ title: "Checkout widget",
+ description: "Add a widget to accept crypto and fiat payments in your app",
+});
+
+# Checkout widget
+
+The Checkout widget makes it easy to accept crypto and fiat payments directly to your wallet. It supports cross-chain payments, fiat onramp via credit/debit cards, and provides a seamless checkout experience for your users.
+
+
+
+
+
+
+
+
+## Features
+
+- Accept payments in crypto or fiat (credit/debit cards)
+- Cross-chain payment support across 85+ blockchains
+- Display product information (name, description, image)
+- Customizable UI with dark and light mode support
+- Display fiat values in multiple currencies
+- Event callbacks to track purchase status (success, error, cancel)
+
+## Get Started
+
+You can integrate the checkout widget into your website using an iframe or a React component.
+
+
+
+## Try it out
+
+
+
diff --git a/apps/portal/src/app/bridge/checkout-widget/react/page.mdx b/apps/portal/src/app/bridge/checkout-widget/react/page.mdx
new file mode 100644
index 00000000000..bf22c659f58
--- /dev/null
+++ b/apps/portal/src/app/bridge/checkout-widget/react/page.mdx
@@ -0,0 +1,98 @@
+import {
+ ArticleIconCard,
+ createMetadata,
+ DocImage,
+} from "@doc";
+import { PlayIcon } from "lucide-react";
+import { ReactIcon } from "@/icons";
+import checkoutWidgetDark from "../checkout-widget-dark.jpg";
+import checkoutWidgetLight from "../checkout-widget.jpg";
+
+export const metadata = createMetadata({
+ image: {
+ title: "Checkout widget component",
+ icon: "payments",
+ },
+ title: "Checkout widget component",
+ description: "Add a widget to accept crypto and fiat payments in your app using a React component",
+});
+
+# Checkout widget component
+
+The Checkout widget component makes it easy to accept crypto and fiat payments in your app using the thirdweb SDK.
+
+
+
+
+
+
+
+
+## Features
+
+- Accept payments in crypto or fiat (credit/debit cards)
+- Cross-chain payment support across 85+ blockchains
+- Display product information (name, description, image)
+- Customizable UI - use prebuilt themes or override with your brand colors
+- Display fiat values in multiple currencies
+- Event callbacks to track purchase status (success, error, cancel)
+
+## Example
+
+You will need a thirdweb project client id to use the `CheckoutWidget` component. You can get your clientId by creating a project in the [thirdweb dashboard](https://thirdweb.com/team).
+
+```tsx
+import { CheckoutWidget } from "thirdweb/react";
+import { createThirdwebClient } from "thirdweb";
+import { base } from "thirdweb/chains";
+
+const client = createThirdwebClient({
+ clientId: "YOUR_THIRDWEB_CLIENT_ID",
+});
+
+function Example() {
+ return (
+
+ );
+}
+```
+
+Make sure to wrap the component containing `CheckoutWidget` with the `ThirdwebProvider` component.
+
+```tsx
+import { ThirdwebProvider } from "thirdweb/react";
+
+function App() {
+ return (
+
+
+
+ );
+}
+```
+
+
+
+## API Reference
+
+
+
+## Try it out
+
+
+
diff --git a/apps/portal/src/app/bridge/sidebar.tsx b/apps/portal/src/app/bridge/sidebar.tsx
index dc3aa31478a..37e4fb4e929 100644
--- a/apps/portal/src/app/bridge/sidebar.tsx
+++ b/apps/portal/src/app/bridge/sidebar.tsx
@@ -19,17 +19,17 @@ export const sidebar: SideBar = {
},
{ separator: true },
{
- name: "Guides",
+ name: "Widgets",
isCollapsible: false,
links: [
- {
- href: `${bridgeSlug}/swap`,
- name: "Swap Tokens",
- },
{
name: "Bridge Widget",
href: `${bridgeSlug}/bridge-widget`,
links: [
+ {
+ href: `${bridgeSlug}/bridge-widget/react`,
+ name: "React Component",
+ },
{
href: `${bridgeSlug}/bridge-widget/iframe`,
name: "Iframe",
@@ -38,12 +38,38 @@ export const sidebar: SideBar = {
href: `${bridgeSlug}/bridge-widget/script`,
name: "Script",
},
+ ],
+ },
+ {
+ name: "Checkout Widget",
+ href: `${bridgeSlug}/checkout-widget`,
+ links: [
{
- href: `${bridgeSlug}/bridge-widget/react`,
+ href: `${bridgeSlug}/checkout-widget/react`,
name: "React Component",
},
+ {
+ href: `${bridgeSlug}/checkout-widget/iframe`,
+ name: "Iframe",
+ },
],
},
+ {
+ name: "Swap Widget",
+ href: `${bridgeSlug}/swap-widget`,
+ },
+ ],
+ },
+ { separator: true },
+ {
+ name: "Guides",
+ isCollapsible: false,
+ links: [
+ {
+ href: `${bridgeSlug}/swap`,
+ name: "Swap Tokens",
+ },
+
{
href: `${bridgeSlug}/fund`,
name: "Fund Wallets",
diff --git a/apps/portal/src/app/bridge/swap-widget/page.mdx b/apps/portal/src/app/bridge/swap-widget/page.mdx
new file mode 100644
index 00000000000..f14ccc3711a
--- /dev/null
+++ b/apps/portal/src/app/bridge/swap-widget/page.mdx
@@ -0,0 +1,157 @@
+import {
+ ArticleIconCard,
+ createMetadata,
+ DocImage,
+} from "@doc";
+import { PlayIcon } from "lucide-react";
+import { ReactIcon } from "@/icons";
+import SwapWidgetDark from "../swap/swap-dark.jpg";
+import SwapWidgetLight from "../swap/swap-light.jpg";
+
+export const metadata = createMetadata({
+ image: {
+ title: "Swap widget",
+ icon: "payments",
+ },
+ title: "Swap widget",
+ description: "Add a widget to swap tokens across chains in your app",
+});
+
+# Swap widget
+
+The Swap widget makes it easy to add cross-chain token swaps to your app using the thirdweb SDK.
+
+
+
+
+
+
+
+
+## Features
+
+- Cross-chain token swaps across 50+ blockchains
+- Real-time quotes with up-to-date pricing
+- Route optimization to find the best path for any token pair
+- Customizable UI - use prebuilt themes or override with your brand colors
+- Prefill token selections for a smoother user experience
+- Event callbacks to track user actions (success, error, cancel)
+
+## Example
+
+You will need a thirdweb project client id to use the `SwapWidget` component. You can get your clientId by creating a project in the [thirdweb dashboard](https://thirdweb.com/team).
+
+```tsx
+import { SwapWidget } from "thirdweb/react";
+import { createThirdwebClient } from "thirdweb";
+
+const client = createThirdwebClient({
+ clientId: "YOUR_THIRDWEB_CLIENT_ID",
+});
+
+function Example() {
+ return ;
+}
+```
+
+Make sure to wrap the component containing `SwapWidget` with the `ThirdwebProvider` component.
+
+```tsx
+import { ThirdwebProvider } from "thirdweb/react";
+
+function App() {
+ return (
+
+
+
+ );
+}
+```
+
+## Configuring Default Token Selection
+
+By default, no tokens are selected in the widget UI. You can configure the default token selection by passing in the `prefill` prop. It only sets the default token selection - users can change these selections in the widget UI.
+
+### Set an ERC20 token to Buy by default
+
+```tsx
+
+```
+
+### Set a native token to Sell by default
+
+To configure a native token to sell by default, you can omit the `tokenAddress` property.
+
+```tsx
+
+```
+
+### Set amount and token to Buy by default
+
+```tsx
+
+```
+
+### Set both buy and sell tokens by default
+
+```tsx
+
+```
+
+## API Reference
+
+
+
+## Try it out
+
+
+
diff --git a/apps/portal/src/app/bridge/swap/page.mdx b/apps/portal/src/app/bridge/swap/page.mdx
index 64a2d163122..318531a27fb 100644
--- a/apps/portal/src/app/bridge/swap/page.mdx
+++ b/apps/portal/src/app/bridge/swap/page.mdx
@@ -12,8 +12,8 @@ import {
ReactIcon,
TypeScriptIcon,
} from "@/icons";
-import SwapWidgetImage from "./swap-dark.png";
-import SwapWidgetImageLight from "./swap-light.png";
+import SwapWidgetImage from "./swap-dark.jpg";
+import SwapWidgetImageLight from "./swap-light.jpg";
export const metadata = createMetadata({
image: {
diff --git a/apps/portal/src/app/bridge/swap/swap-dark.jpg b/apps/portal/src/app/bridge/swap/swap-dark.jpg
new file mode 100644
index 00000000000..e4f56efe076
Binary files /dev/null and b/apps/portal/src/app/bridge/swap/swap-dark.jpg differ
diff --git a/apps/portal/src/app/bridge/swap/swap-dark.png b/apps/portal/src/app/bridge/swap/swap-dark.png
deleted file mode 100644
index 267571d55b9..00000000000
Binary files a/apps/portal/src/app/bridge/swap/swap-dark.png and /dev/null differ
diff --git a/apps/portal/src/app/bridge/swap/swap-light.jpg b/apps/portal/src/app/bridge/swap/swap-light.jpg
new file mode 100644
index 00000000000..3134a46f529
Binary files /dev/null and b/apps/portal/src/app/bridge/swap/swap-light.jpg differ
diff --git a/apps/portal/src/app/bridge/swap/swap-light.png b/apps/portal/src/app/bridge/swap/swap-light.png
deleted file mode 100644
index 26ceef282d0..00000000000
Binary files a/apps/portal/src/app/bridge/swap/swap-light.png and /dev/null differ