From 41919024c3f5ddcfd252c35d69dd21d4495d8bc7 Mon Sep 17 00:00:00 2001 From: MananTank Date: Wed, 10 Dec 2025 17:53:09 +0000 Subject: [PATCH] Add bridge widget iframe docs, update path, link to docs (#8528) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ## PR-Codex overview This PR focuses on enhancing the `Bridge` and `Bridge Widget` functionalities, improving UI elements, adding new features, and updating documentation. It includes modifications to components, styling adjustments, and expanded capabilities for currency selection. ### Detailed summary - Updated `Sidebar.tsx` to remove padding. - Changed `page.mdx` headers from "Key Features" to "Features". - Enhanced `reportBridgePageLinkClick` to include "integrate-bridge-widget". - Modified `page.tsx` to include client ID instructions. - Adjusted header font sizes in `header.tsx`. - Improved `bridgeRedirects` to include new paths. - Updated `bridge-widget` links in `sidebar.tsx`. - Added `persistTokenSelections` and `currency` props to `UniversalBridgeEmbed`. - Created `IframeCodePreview` component for iframe integration documentation. - Added a new `BadgeLink` component for better user interaction. - Expanded `BuyAndSwapEmbed` props to support currency and token selections. - Updated documentation for `BridgeWidget` and `Iframe` integrations with examples. - Enhanced `BridgePageUI` to include the new `AddBridgeWidgetLink`. - Introduced multiple currency options for fiat values in widget interfaces. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` ## Summary by CodeRabbit * **New Features** * Bridge widget available via Iframe, Script, and React component * Fiat currency selection for buy/swap widgets * Token selection persistence option * "Add Bridge widget" integration link added to Bridge page * **Documentation** * New detailed guides and examples for Iframe, Script, and React integration * Code preview and embedding examples added * **Style** * Typography, spacing, and layout refinements across Bridge pages * Navigation reorganized into a Bridge Widget group * **Chores** * Added redirects for Bridge widget paths ✏️ Tip: You can customize this high-level summary in your review settings. --- apps/dashboard/src/@/analytics/report.ts | 2 +- .../@/components/blocks/BuyAndSwapEmbed.tsx | 11 +- .../(general)/components/bridge-page.tsx | 13 +- .../client/UniversalBridgeEmbed.tsx | 5 + .../components/client/badge-link.tsx | 34 ++++ .../bridge/(general)/components/header.tsx | 4 +- .../src/app/bridge/(general)/page.tsx | 2 +- .../app/bridge/{embed => widget}/layout.tsx | 0 .../{embed => widget}/opengraph-image.png | Bin .../src/app/bridge/{embed => widget}/page.tsx | 40 +++++ apps/portal/redirects.mjs | 5 + .../bridge-widget-dark.png | Bin .../bridge-widget-light.png | Bin .../iframe/iframe-code-preview.tsx | 33 ++++ .../app/bridge/bridge-widget/iframe/page.mdx | 153 ++++++++++++++++++ .../src/app/bridge/bridge-widget/page.mdx | 61 +++++++ .../app/bridge/bridge-widget/react/page.mdx | 83 ++++++++++ .../script}/page.mdx | 17 +- apps/portal/src/app/bridge/page.mdx | 3 +- apps/portal/src/app/bridge/sidebar.tsx | 18 ++- apps/portal/src/app/bridge/swap/page.mdx | 2 +- apps/portal/src/components/others/Sidebar.tsx | 2 +- packages/thirdweb/src/exports/react.ts | 1 + .../ui/Bridge/bridge-widget/bridge-widget.tsx | 6 - 24 files changed, 467 insertions(+), 28 deletions(-) create mode 100644 apps/dashboard/src/app/bridge/(general)/components/client/badge-link.tsx rename apps/dashboard/src/app/bridge/{embed => widget}/layout.tsx (100%) rename apps/dashboard/src/app/bridge/{embed => widget}/opengraph-image.png (100%) rename apps/dashboard/src/app/bridge/{embed => widget}/page.tsx (80%) rename apps/portal/src/app/bridge/{bridge-widget-script => bridge-widget}/bridge-widget-dark.png (100%) rename apps/portal/src/app/bridge/{bridge-widget-script => bridge-widget}/bridge-widget-light.png (100%) create mode 100644 apps/portal/src/app/bridge/bridge-widget/iframe/iframe-code-preview.tsx create mode 100644 apps/portal/src/app/bridge/bridge-widget/iframe/page.mdx create mode 100644 apps/portal/src/app/bridge/bridge-widget/page.mdx create mode 100644 apps/portal/src/app/bridge/bridge-widget/react/page.mdx rename apps/portal/src/app/bridge/{bridge-widget-script => bridge-widget/script}/page.mdx (95%) diff --git a/apps/dashboard/src/@/analytics/report.ts b/apps/dashboard/src/@/analytics/report.ts index 22b6bec7b38..c054a150872 100644 --- a/apps/dashboard/src/@/analytics/report.ts +++ b/apps/dashboard/src/@/analytics/report.ts @@ -683,7 +683,7 @@ export function reportProductFeedback(properties: { * */ export function reportBridgePageLinkClick(params: { - linkType: "bridge-docs" | "trending-tokens"; + linkType: "bridge-docs" | "trending-tokens" | "integrate-bridge-widget"; }) { posthog.capture("bridge page link clicked", params); } diff --git a/apps/dashboard/src/@/components/blocks/BuyAndSwapEmbed.tsx b/apps/dashboard/src/@/components/blocks/BuyAndSwapEmbed.tsx index 3ffadd77679..d41b0d6479e 100644 --- a/apps/dashboard/src/@/components/blocks/BuyAndSwapEmbed.tsx +++ b/apps/dashboard/src/@/components/blocks/BuyAndSwapEmbed.tsx @@ -4,7 +4,11 @@ import { useTheme } from "next-themes"; import { useEffect, useMemo, useRef, useState } from "react"; import { defineChain } from "thirdweb"; -import { BuyWidget, SwapWidget } from "thirdweb/react"; +import { + BuyWidget, + type SupportedFiatCurrency, + SwapWidget, +} from "thirdweb/react"; import type { Wallet } from "thirdweb/wallets"; import { reportAssetBuyCancelled, @@ -34,6 +38,7 @@ import { getConfiguredThirdwebClient } from "../../constants/thirdweb.server"; type PageType = "asset" | "bridge" | "chain" | "bridge-iframe"; export type BuyAndSwapEmbedProps = { + persistTokenSelections?: boolean; buyTab: | { buyToken: @@ -65,6 +70,7 @@ export type BuyAndSwapEmbedProps = { | undefined; pageType: PageType; wallets?: Wallet[]; + currency?: SupportedFiatCurrency; }; export function BuyAndSwapEmbed(props: BuyAndSwapEmbedProps) { @@ -118,6 +124,7 @@ export function BuyAndSwapEmbed(props: BuyAndSwapEmbedProps) { {tab === "buy" && ( +
+ +
+ +
+
@@ -43,7 +50,7 @@ export function BridgePageUI(props: { function HeadingSection(props: { title: React.ReactNode }) { return (
-
{props.title}
+
{props.title}

Seamlessly move your assets across {bridgeStats.supportedChains} chains @@ -81,9 +88,9 @@ function DataSquare(props: { imageClassName?: string; }) { return ( -

+
-
+
{ + reportBridgePageLinkClick({ linkType: "integrate-bridge-widget" }); + }} + /> + ); +} + +function BadgeLink(props: { + href: string; + label: string; + onClick?: () => void; +}) { + return ( + + {props.label} + + + ); +} diff --git a/apps/dashboard/src/app/bridge/(general)/components/header.tsx b/apps/dashboard/src/app/bridge/(general)/components/header.tsx index fdf785aebe5..635696b226e 100644 --- a/apps/dashboard/src/app/bridge/(general)/components/header.tsx +++ b/apps/dashboard/src/app/bridge/(general)/components/header.tsx @@ -13,10 +13,10 @@ import { bridgeWallets } from "./client/UniversalBridgeEmbed"; export function BridgePageHeader(props: { containerClassName?: string }) { return ( -
+
diff --git a/apps/dashboard/src/app/bridge/(general)/page.tsx b/apps/dashboard/src/app/bridge/(general)/page.tsx index b2f8877db8e..f2383681f1a 100644 --- a/apps/dashboard/src/app/bridge/(general)/page.tsx +++ b/apps/dashboard/src/app/bridge/(general)/page.tsx @@ -60,7 +60,7 @@ export default async function Page(props: { : undefined, }} title={ -

+

Bridge and Swap tokens
across any chain, instantly

diff --git a/apps/dashboard/src/app/bridge/embed/layout.tsx b/apps/dashboard/src/app/bridge/widget/layout.tsx similarity index 100% rename from apps/dashboard/src/app/bridge/embed/layout.tsx rename to apps/dashboard/src/app/bridge/widget/layout.tsx diff --git a/apps/dashboard/src/app/bridge/embed/opengraph-image.png b/apps/dashboard/src/app/bridge/widget/opengraph-image.png similarity index 100% rename from apps/dashboard/src/app/bridge/embed/opengraph-image.png rename to apps/dashboard/src/app/bridge/widget/opengraph-image.png diff --git a/apps/dashboard/src/app/bridge/embed/page.tsx b/apps/dashboard/src/app/bridge/widget/page.tsx similarity index 80% rename from apps/dashboard/src/app/bridge/embed/page.tsx rename to apps/dashboard/src/app/bridge/widget/page.tsx index 3bee0a0c9dc..815686bbe1b 100644 --- a/apps/dashboard/src/app/bridge/embed/page.tsx +++ b/apps/dashboard/src/app/bridge/widget/page.tsx @@ -3,6 +3,7 @@ import { isAddress, NATIVE_TOKEN_ADDRESS } from "thirdweb"; import { UniversalBridgeEmbed } from "../(general)/components/client/UniversalBridgeEmbed"; import { bridgeStats } from "../(general)/data"; import "@workspace/ui/global.css"; +import type { SupportedFiatCurrency } from "thirdweb/react"; import { NEXT_PUBLIC_BRIDGE_IFRAME_CLIENT_ID } from "@/constants/public-envs"; import { BridgeProviders } from "../(general)/components/client/Providers.client"; @@ -38,15 +39,28 @@ export default async function Page(props: { const buyChain = parse(searchParams.outputChain, onlyNumber); const buyCurrency = parse(searchParams.outputCurrency, onlyAddress); + const persistTokenSelections = + parse(searchParams.persistTokenSelections, (v) => + v === "false" ? "false" : "true", + ) || "true"; + const theme = parse(searchParams.theme, (v) => (v === "light" ? "light" : "dark")) || "dark"; + const currency = parse(searchParams.currency, (v) => + VALID_CURRENCIES.includes(v as SupportedFiatCurrency) + ? (v as SupportedFiatCurrency) + : undefined, + ); + return (
( value: string | string[] | undefined, fn: (value: string) => T | undefined, diff --git a/apps/portal/redirects.mjs b/apps/portal/redirects.mjs index ac62178ca3c..1a87cbb4eab 100644 --- a/apps/portal/redirects.mjs +++ b/apps/portal/redirects.mjs @@ -1093,6 +1093,10 @@ const walletRefactorRedirects = { "/typescript/v5/supported-wallets/:path*": "/wallets/external-wallets", }; +const bridgeRedirects = { + "/bridge/bridge-widget-script": "/bridge/bridge-widget/script", +}; + /** * @type {import('next').NextConfig['redirects']} */ @@ -1115,6 +1119,7 @@ export const redirects = async () => { ...createRedirects(glossaryRedirects), ...createRedirects(payRedirects), ...createRedirects(walletRefactorRedirects), + ...createRedirects(bridgeRedirects), ]; }; diff --git a/apps/portal/src/app/bridge/bridge-widget-script/bridge-widget-dark.png b/apps/portal/src/app/bridge/bridge-widget/bridge-widget-dark.png similarity index 100% rename from apps/portal/src/app/bridge/bridge-widget-script/bridge-widget-dark.png rename to apps/portal/src/app/bridge/bridge-widget/bridge-widget-dark.png diff --git a/apps/portal/src/app/bridge/bridge-widget-script/bridge-widget-light.png b/apps/portal/src/app/bridge/bridge-widget/bridge-widget-light.png similarity index 100% rename from apps/portal/src/app/bridge/bridge-widget-script/bridge-widget-light.png rename to apps/portal/src/app/bridge/bridge-widget/bridge-widget-light.png diff --git a/apps/portal/src/app/bridge/bridge-widget/iframe/iframe-code-preview.tsx b/apps/portal/src/app/bridge/bridge-widget/iframe/iframe-code-preview.tsx new file mode 100644 index 00000000000..b390253c997 --- /dev/null +++ b/apps/portal/src/app/bridge/bridge-widget/iframe/iframe-code-preview.tsx @@ -0,0 +1,33 @@ +import { CodeBlock, Tabs, TabsContent, TabsList, TabsTrigger } from "@doc"; + +export function IframeCodePreview(props: { src: string }) { + return ( + + + Code + Preview + + + `} + lang="html" + /> + + +