- )}
- >
- );
-}
diff --git a/apps/playground-web/src/app/wallets/account-abstraction/eip-4337/page.tsx b/apps/playground-web/src/app/account-abstraction/eip-4337/page.tsx
similarity index 79%
rename from apps/playground-web/src/app/wallets/account-abstraction/eip-4337/page.tsx
rename to apps/playground-web/src/app/account-abstraction/eip-4337/page.tsx
index 2474d99f46a..8239abd33af 100644
--- a/apps/playground-web/src/app/wallets/account-abstraction/eip-4337/page.tsx
+++ b/apps/playground-web/src/app/account-abstraction/eip-4337/page.tsx
@@ -1,27 +1,33 @@
-import type { Metadata } from "next";
+import { ShieldIcon } from "lucide-react";
import ThirdwebProvider from "@/components/thirdweb-provider";
-import { metadataBase } from "@/lib/constants";
-import { ConnectSmartAccountCustomPreview } from "../../../../components/account-abstraction/connect-smart-account";
-import { SponsoredTxPreview } from "../../../../components/account-abstraction/sponsored-tx";
-import { PageLayout } from "../../../../components/blocks/APIHeader";
-import { CodeExample } from "../../../../components/code/code-example";
-import { SponsoredInAppTxPreview } from "../../../../components/in-app-wallet/sponsored-tx";
+import { createMetadata } from "@/lib/metadata";
+import { ConnectSmartAccountCustomPreview } from "../../../components/account-abstraction/connect-smart-account";
+import { SponsoredTxPreview } from "../../../components/account-abstraction/sponsored-tx";
+import { PageLayout } from "../../../components/blocks/APIHeader";
+import { CodeExample } from "../../../components/code/code-example";
+import { SponsoredInAppTxPreview } from "../../../components/in-app-wallet/sponsored-tx";
-export const metadata: Metadata = {
- description: "Turn any EOA into a smart contract wallet with EIP-4337.",
- metadataBase,
- title: "EIP-4337 Smart Contract Wallets | thirdweb Connect",
-};
+const title = "Account Abstraction EIP-4337";
+const description =
+ "Enable account abstraction with EIP-4337. Unlock gasless transactions, session keys, paymaster support, and smart wallet programmability";
+
+export const metadata = createMetadata({
+ description,
+ title,
+ image: {
+ icon: "wallets",
+ title,
+ },
+});
export default function Page() {
return (
Turn any EOA into a smart contract wallet with EIP-4337.>
- }
+ icon={ShieldIcon}
+ title={title}
+ description={description}
docsLink="https://portal.thirdweb.com/wallets/sponsor-gas?utm_source=playground"
- title="EIP-4337 Smart Contract Wallets"
>
diff --git a/apps/playground-web/src/app/wallets/account-abstraction/eip-5792/page.tsx b/apps/playground-web/src/app/account-abstraction/eip-5792/page.tsx
similarity index 70%
rename from apps/playground-web/src/app/wallets/account-abstraction/eip-5792/page.tsx
rename to apps/playground-web/src/app/account-abstraction/eip-5792/page.tsx
index b3549777ce1..f4195249532 100644
--- a/apps/playground-web/src/app/wallets/account-abstraction/eip-5792/page.tsx
+++ b/apps/playground-web/src/app/account-abstraction/eip-5792/page.tsx
@@ -1,30 +1,32 @@
-import type { Metadata } from "next";
+import { ShieldIcon } from "lucide-react";
import ThirdwebProvider from "@/components/thirdweb-provider";
-import { metadataBase } from "@/lib/constants";
-import { Eip5792GetCapabilitiesPreview } from "../../../../components/account-abstraction/5792-get-capabilities";
-import { Eip5792SendCallsPreview } from "../../../../components/account-abstraction/5792-send-calls";
-import { PageLayout } from "../../../../components/blocks/APIHeader";
-import { CodeExample } from "../../../../components/code/code-example";
+import { Eip5792GetCapabilitiesPreview } from "../../../components/account-abstraction/5792-get-capabilities";
+import { Eip5792SendCallsPreview } from "../../../components/account-abstraction/5792-send-calls";
+import { PageLayout } from "../../../components/blocks/APIHeader";
+import { CodeExample } from "../../../components/code/code-example";
+import { createMetadata } from "../../../lib/metadata";
-export const metadata: Metadata = {
- description:
- "EIP-5792 capabilities allow you to view the capabilities of the connected wallet",
- metadataBase,
- title: "EIP-5792 Wallet Capabilities | thirdweb Connect",
-};
+const title = "Account Abstraction EIP-5792";
+const description =
+ "EIP-5792 brings a standard for abstracted actions—combine transaction batching, bundling, and paymasters with a unified smart account interface";
+
+export const metadata = createMetadata({
+ description,
+ title,
+ image: {
+ icon: "wallets",
+ title,
+ },
+});
export default function Page() {
return (
- EIP-5792 capabilities allow you to view the capabilities of the
- connected wallet.
- >
- }
+ icon={ShieldIcon}
+ title={title}
+ description={description}
docsLink="https://portal.thirdweb.com/wallets/sponsor-gas?utm_source=playground"
- title="EIP-5792 Wallet Capabilities"
>
diff --git a/apps/playground-web/src/app/wallets/account-abstraction/eip-7702/page.tsx b/apps/playground-web/src/app/account-abstraction/eip-7702/page.tsx
similarity index 60%
rename from apps/playground-web/src/app/wallets/account-abstraction/eip-7702/page.tsx
rename to apps/playground-web/src/app/account-abstraction/eip-7702/page.tsx
index 21c07b7a75e..3c85d6e6874 100644
--- a/apps/playground-web/src/app/wallets/account-abstraction/eip-7702/page.tsx
+++ b/apps/playground-web/src/app/account-abstraction/eip-7702/page.tsx
@@ -1,29 +1,33 @@
-import type { Metadata } from "next";
+import { ShieldIcon } from "lucide-react";
import ThirdwebProvider from "@/components/thirdweb-provider";
-import { metadataBase } from "@/lib/constants";
-import { Eip7702SmartAccountPreview } from "../../../../components/account-abstraction/7702-smart-account";
-import { PageLayout } from "../../../../components/blocks/APIHeader";
-import { CodeExample } from "../../../../components/code/code-example";
+import { Eip7702SmartAccountPreview } from "../../../components/account-abstraction/7702-smart-account";
+import { PageLayout } from "../../../components/blocks/APIHeader";
+import { CodeExample } from "../../../components/code/code-example";
+import { createMetadata } from "../../../lib/metadata";
-export const metadata: Metadata = {
- description:
- "EIP-7702 smart accounts allow you to turn your EOA into a smart account with no code changes",
- metadataBase,
- title: "EIP-7702 Smart Accounts | thirdweb Connect",
-};
+const title = "Account Abstraction EIP-7702";
+const description =
+ "Enable account abstraction with EIP-7702. Unlock gasless transactions, session keys, paymaster support, and smart wallet programmability";
+const ogDescription =
+ "Use EIP-7702 to upgrade EOAs into temporary smart accounts. Bring native account abstraction to any wallet, enabling gasless transactions and advanced logic.";
+
+export const metadata = createMetadata({
+ description: ogDescription,
+ title,
+ image: {
+ icon: "wallets",
+ title,
+ },
+});
export default function Page() {
return (
- EIP-7702 smart accounts allow you to turn your EOA into a smart
- account with no code changes.
- >
- }
+ icon={ShieldIcon}
+ description={description}
docsLink="https://portal.thirdweb.com/wallets/sponsor-gas?utm_source=playground"
- title="EIP-7702 Smart Accounts"
+ title={title}
>
diff --git a/apps/playground-web/src/app/wallets/account-abstraction/native-aa/page.tsx b/apps/playground-web/src/app/account-abstraction/native-aa/page.tsx
similarity index 62%
rename from apps/playground-web/src/app/wallets/account-abstraction/native-aa/page.tsx
rename to apps/playground-web/src/app/account-abstraction/native-aa/page.tsx
index 17cb4e4106f..04c2def05db 100644
--- a/apps/playground-web/src/app/wallets/account-abstraction/native-aa/page.tsx
+++ b/apps/playground-web/src/app/account-abstraction/native-aa/page.tsx
@@ -1,29 +1,31 @@
-import type { Metadata } from "next";
+import { ShieldIcon } from "lucide-react";
import ThirdwebProvider from "@/components/thirdweb-provider";
-import { metadataBase } from "@/lib/constants";
-import { SponsoredTxZksyncPreview } from "../../../../components/account-abstraction/sponsored-tx-zksync";
-import { PageLayout } from "../../../../components/blocks/APIHeader";
-import { CodeExample } from "../../../../components/code/code-example";
+import { createMetadata } from "@/lib/metadata";
+import { SponsoredTxZksyncPreview } from "../../../components/account-abstraction/sponsored-tx-zksync";
+import { PageLayout } from "../../../components/blocks/APIHeader";
+import { CodeExample } from "../../../components/code/code-example";
-export const metadata: Metadata = {
- description:
- "On zkSync chains, you can take advantage of native account abstraction with no code changes",
- metadataBase,
- title: "Native Account Abstraction",
-};
+const title = "Native Account Abstraction Through zkSync";
+const description =
+ "Leverage native account abstraction on zkSync. Use smart accounts out of the box for gasless transactions, batching, and flexible signing logic";
+
+export const metadata = createMetadata({
+ description,
+ title,
+ image: {
+ icon: "wallets",
+ title,
+ },
+});
export default function Page() {
return (
- On zkSync chains, you can take advantage of native account
- abstraction with no code changes.
- >
- }
+ icon={ShieldIcon}
+ title={title}
+ description={description}
docsLink="https://portal.thirdweb.com/wallets/sponsor-gas?utm_source=playground"
- title="Native Account Abstraction"
>
diff --git a/apps/playground-web/src/app/api/og/inter/700.ttf b/apps/playground-web/src/app/api/og/inter/700.ttf
new file mode 100644
index 00000000000..8e82c70d108
Binary files /dev/null and b/apps/playground-web/src/app/api/og/inter/700.ttf differ
diff --git a/apps/playground-web/src/app/api/og/route.tsx b/apps/playground-web/src/app/api/og/route.tsx
new file mode 100644
index 00000000000..0ba52752883
--- /dev/null
+++ b/apps/playground-web/src/app/api/og/route.tsx
@@ -0,0 +1,108 @@
+/* eslint-disable @next/next/no-img-element */
+import { ImageResponse } from "next/og";
+import { getBaseUrl } from "@/lib/env";
+
+export const runtime = "edge";
+
+const BASE_URL = getBaseUrl();
+
+const width = 1200;
+const height = 630;
+
+const iconSize = 400;
+
+const inter600 = fetch(new URL("./inter/700.ttf", import.meta.url)).then(
+ (res) => res.arrayBuffer(),
+);
+
+export async function GET(request: Request) {
+ const { searchParams } = new URL(request.url);
+
+ const icon = searchParams.get("icon");
+ const title = searchParams.get("title");
+
+ if (!icon || !title) {
+ return new Response("Failed to generate the image", {
+ status: 500,
+ });
+ }
+
+ const iconUrl = `${BASE_URL}/og/icons/${icon}.svg`;
+
+ return new ImageResponse(
+ // ImageResponse JSX element
+
+
+
+ {/* Left */}
+
+
+ {title}
+
+
+
+
+
,
+ // ImageResponse options
+ {
+ fonts: [
+ {
+ data: await inter600,
+ name: "Inter",
+ style: "normal",
+ weight: 600,
+ },
+ ],
+ height: height,
+ width: width,
+ },
+ );
+}
diff --git a/apps/playground-web/src/app/contracts/events/page.tsx b/apps/playground-web/src/app/contracts/events/page.tsx
new file mode 100644
index 00000000000..9d4fc116471
--- /dev/null
+++ b/apps/playground-web/src/app/contracts/events/page.tsx
@@ -0,0 +1,71 @@
+import { RssIcon } from "lucide-react";
+import { WatchEventPreview } from "@/components/blockchain-api/watch-event-preview";
+import { CodeExample } from "@/components/code/code-example";
+import ThirdwebProvider from "@/components/thirdweb-provider";
+import { PageLayout } from "../../../components/blocks/APIHeader";
+import { createMetadata } from "../../../lib/metadata";
+
+const title = "Listen Contract Events";
+const description =
+ "Subscribe to any contract event with auto-polling hooks and type-safe event handlers. Supports all common standards out of the box";
+
+const ogDescription =
+ "Listen to blockchain contract events using auto-polling hooks and type-safe functions. Supports ERC20, ERC721, and other common Web3 standards with minimal setup.";
+
+export const metadata = createMetadata({
+ title,
+ description: ogDescription,
+ image: {
+ icon: "contract",
+ title,
+ },
+});
+
+export default function Page() {
+ return (
+
+
+
+
+
+ );
+}
+
+function WatchEvent() {
+ return (
+ {
+ const { from, to, value } = item.args;
+ console.log("{from}...{value} USDC...{to}");
+ });
+}
+`}
+ lang="tsx"
+ preview={}
+ />
+ );
+}
diff --git a/apps/playground-web/src/app/contracts/extensions/page.tsx b/apps/playground-web/src/app/contracts/extensions/page.tsx
new file mode 100644
index 00000000000..f4e416eaa5b
--- /dev/null
+++ b/apps/playground-web/src/app/contracts/extensions/page.tsx
@@ -0,0 +1,117 @@
+import { BlocksIcon } from "lucide-react";
+import { ReadContractExtensionPreview } from "@/components/blockchain-api/read-contract-extension";
+import { WriteContractExtensionPreview } from "@/components/blockchain-api/write-contract-extension";
+import { CodeExample } from "@/components/code/code-example";
+import ThirdwebProvider from "@/components/thirdweb-provider";
+import { PageLayout } from "../../../components/blocks/APIHeader";
+import { createMetadata } from "../../../lib/metadata";
+
+const title = "Pre-Built Extensions";
+const description =
+ "High-level ready and write functions with built-in pre/post-processing for common standards.";
+
+const ogDescription =
+ "Simplify smart contract reads and writes with prebuilt extensions. Handle approvals, formatting, and standards with built-in pre/post-processing.";
+
+export const metadata = createMetadata({
+ title,
+ description: ogDescription,
+ image: {
+ icon: "contract",
+ title,
+ },
+});
+
+export default function Page() {
+ return (
+
+
+
+
+
+
+
+
+ );
+}
+
+function ReadContractExtension() {
+ return (
+
+ );
+}
+`}
+ header={{
+ description:
+ "Extensions let you do more with less code. High level functions with simple API that do pre and post processing for all common standards.",
+ title: "Prebuilt read extensions",
+ }}
+ lang="tsx"
+ preview={}
+ />
+ );
+}
+
+function WriteContractExtension() {
+ return (
+
+ claimTo({
+ contract: twCoinContract,
+ to: account.address,
+ quantity: "10",
+ })
+ }
+ >
+ Claim
+
+}
+`}
+ header={{
+ description:
+ "Extensions let you do more with less code. High level functions with simple API that do pre and post processing for all common standards.",
+ title: "Prebuilt write extensions",
+ }}
+ lang="tsx"
+ preview={}
+ />
+ );
+}
diff --git a/apps/playground-web/src/app/contracts/read/page.tsx b/apps/playground-web/src/app/contracts/read/page.tsx
new file mode 100644
index 00000000000..5696501581f
--- /dev/null
+++ b/apps/playground-web/src/app/contracts/read/page.tsx
@@ -0,0 +1,73 @@
+import { ScanTextIcon } from "lucide-react";
+import { ReadContractRawPreview } from "@/components/blockchain-api/read-contract-raw";
+import { PageLayout } from "@/components/blocks/APIHeader";
+import { CodeExample } from "@/components/code/code-example";
+import ThirdwebProvider from "@/components/thirdweb-provider";
+import { createMetadata } from "@/lib/metadata";
+
+const title = "Read Contract Data";
+const description =
+ "Read data from any contract on EVM with Type safe functions and hooks without needing contract ABIs";
+const ogDescription =
+ "Query smart contracts and wallet data using type-safe functions and React hooks—no ABI required. Read blockchain data with full type safety";
+
+export const metadata = createMetadata({
+ title,
+ description: ogDescription,
+ image: {
+ icon: "contract",
+ title,
+ },
+});
+
+export default function Page() {
+ return (
+
+
+
+
+
+
+
+ );
+}
+
+function ReadContractRaw() {
+ return (
+
+ );
+}
+`}
+ lang="tsx"
+ preview={}
+ />
+ );
+}
diff --git a/apps/playground-web/src/app/contracts/write/page.tsx b/apps/playground-web/src/app/contracts/write/page.tsx
new file mode 100644
index 00000000000..0197d463ef7
--- /dev/null
+++ b/apps/playground-web/src/app/contracts/write/page.tsx
@@ -0,0 +1,76 @@
+import { PencilIcon } from "lucide-react";
+import { WriteContractRawPreview } from "@/components/blockchain-api/write-contract-raw";
+import { CodeExample } from "@/components/code/code-example";
+import ThirdwebProvider from "@/components/thirdweb-provider";
+import { PageLayout } from "../../../components/blocks/APIHeader";
+import { createMetadata } from "../../../lib/metadata";
+
+const title = "Write Contract";
+const description =
+ "Send transactions from the connected wallet using type-safe functions and hooks for contract calls or raw transactions";
+
+const ogDescription =
+ "Send blockchain transactions with the connected wallet using type-safe functions and React hooks for contract calls or raw transactions";
+
+export const metadata = createMetadata({
+ title,
+ description: ogDescription,
+ image: {
+ icon: "contract",
+ title,
+ },
+});
+
+export default function Page() {
+ return (
+
+
+
+ );
}
diff --git a/apps/playground-web/src/app/payments/backend/layout.tsx b/apps/playground-web/src/app/payments/backend/layout.tsx
index acebc58595b..efd08171f3b 100644
--- a/apps/playground-web/src/app/payments/backend/layout.tsx
+++ b/apps/playground-web/src/app/payments/backend/layout.tsx
@@ -1,15 +1,32 @@
+import { BracesIcon } from "lucide-react";
import type React from "react";
-import { PageHeader } from "../../../components/blocks/APIHeader";
+import { PageHeader } from "@/components/blocks/APIHeader";
+import { createMetadata } from "@/lib/metadata";
+
+const title = "Payments API";
+const description =
+ "Create customizable components or backend flows with an HTTP API to onramp, swap, and bridge to and from different cryptocurrencies";
+const ogDescription =
+ "Bridge, swap, and onramp any currency with thirdweb’s Payments REST API. Use simple HTTP requests to integrate from your backend.";
+
+export const metadata = createMetadata({
+ description: ogDescription,
+ title,
+ image: {
+ icon: "payments",
+ title,
+ },
+});
export default function Layout(props: { children: React.ReactNode }) {
return (
HTTP API to bridge, swap and onramp to and from any currency>
- }
+ description={description}
docsLink="https://portal.thirdweb.com/payments?utm_source=playground"
- title="Payments API"
+ icon={BracesIcon}
+ title={title}
+ containerClassName="max-w-[1400px]"
/>
{props.children}
diff --git a/apps/playground-web/src/app/payments/backend/page.tsx b/apps/playground-web/src/app/payments/backend/page.tsx
index 6a8d1e4f6c0..91685528891 100644
--- a/apps/playground-web/src/app/payments/backend/page.tsx
+++ b/apps/playground-web/src/app/payments/backend/page.tsx
@@ -1,3 +1,4 @@
+import { ArrowUpRightIcon } from "lucide-react";
import Link from "next/link";
import { Button } from "@/components/ui/button";
import { Table, TableBody, TableCell, TableRow } from "@/components/ui/table";
@@ -7,10 +8,10 @@ export default async function Page() {
try {
const paths = await getBridgePaths();
return (
-
+
-
+
thirdweb Payments REST API
@@ -20,8 +21,13 @@ export default async function Page() {
-
diff --git a/apps/playground-web/src/app/payments/backend/reference/page.tsx b/apps/playground-web/src/app/payments/backend/reference/page.tsx
index 44e2057f2a9..1f0753622ce 100644
--- a/apps/playground-web/src/app/payments/backend/reference/page.tsx
+++ b/apps/playground-web/src/app/payments/backend/reference/page.tsx
@@ -36,7 +36,7 @@ export default async function Page(props: {
const title = pathMetadata.summary || "";
return (
-
+
{title && (
diff --git a/apps/playground-web/src/app/payments/commerce/page.tsx b/apps/playground-web/src/app/payments/commerce/page.tsx
index 6b99c528123..2f1fc22d8bb 100644
--- a/apps/playground-web/src/app/payments/commerce/page.tsx
+++ b/apps/playground-web/src/app/payments/commerce/page.tsx
@@ -1,28 +1,33 @@
-import type { Metadata } from "next";
+import { CreditCardIcon } from "lucide-react";
import { PageLayout } from "@/components/blocks/APIHeader";
import { CodeExample } from "@/components/code/code-example";
import { BuyMerchPreview } from "@/components/pay/direct-payment";
import ThirdwebProvider from "@/components/thirdweb-provider";
-import { metadataBase } from "@/lib/constants";
+import { createMetadata } from "@/lib/metadata";
-export const metadata: Metadata = {
- description:
- "The easiest way for users to transact in your app. Onramp users in clicks and generate revenue for each user transaction. Integrate for free.",
- metadataBase,
- title: "Integrate Fiat & Cross-Chain Crypto Payments | thirdweb Payments",
-};
+const title = "Checkout Component";
+const description =
+ "Enable purchase of any service or goods with fiat or cryptocurrency and setup notifications on every sale to ship goods, activate services, and more";
+const ogDescription =
+ "Accept fiat or crypto payments on any chain—direct to your wallet. Instant checkout, webhook support, and full control over post-sale actions.";
+
+export const metadata = createMetadata({
+ description: ogDescription,
+ title,
+ image: {
+ icon: "payments",
+ title,
+ },
+});
export default function Page() {
return (
- Let your users pay for any service with fiat or crypto on any chain.
- >
- }
+ icon={CreditCardIcon}
+ title={title}
+ description={description}
docsLink="https://portal.thirdweb.com/payments?utm_source=playground"
- title="Commerce payments with fiat or crypto"
>
diff --git a/apps/playground-web/src/app/payments/fund-wallet/page.tsx b/apps/playground-web/src/app/payments/fund-wallet/page.tsx
index 6d09963ea87..c16f446a36d 100644
--- a/apps/playground-web/src/app/payments/fund-wallet/page.tsx
+++ b/apps/playground-web/src/app/payments/fund-wallet/page.tsx
@@ -1,29 +1,33 @@
-import type { Metadata } from "next";
+import { ShoppingBagIcon } from "lucide-react";
import { PageLayout } from "@/components/blocks/APIHeader";
import { CodeExample } from "@/components/code/code-example";
import ThirdwebProvider from "@/components/thirdweb-provider";
import { StyledBuyWidgetPreview } from "@/components/universal-bridge/buy";
-import { metadataBase } from "@/lib/constants";
+import { createMetadata } from "@/lib/metadata";
-export const metadata: Metadata = {
- description:
- "The easiest way for users to fund their wallets. Onramp users in clicks and generate revenue for each user transaction. Integrate for free.",
- metadataBase,
- title: "Buy Crypto | thirdweb Payments",
-};
+const title = "Buy Crypto Component";
+const description =
+ "Embeddable component for users to purchase any cryptocurrency for top-ups and more with fiat or crypto-to-crypto swaps";
+const ogDescription =
+ "Configure a component to buy cryptocurrency with specified amounts, customization, and more. This interactive playground shows how to customize the component.";
+
+export const metadata = createMetadata({
+ description: ogDescription,
+ title,
+ image: {
+ icon: "payments",
+ title,
+ },
+});
export default function Page() {
return (
- Onramp users with credit card & cross-chain crypto payments —
- and generate revenue for each user transaction.
- >
- }
+ icon={ShoppingBagIcon}
+ title={title}
+ description={description}
docsLink="https://portal.thirdweb.com/wallets/sponsor-gas?utm_source=playground"
- title="The easiest way for users to fund their wallets"
>
diff --git a/apps/playground-web/src/app/payments/opengraph-image.png b/apps/playground-web/src/app/payments/opengraph-image.png
deleted file mode 100644
index 7a71cef0b4a..00000000000
Binary files a/apps/playground-web/src/app/payments/opengraph-image.png and /dev/null differ
diff --git a/apps/playground-web/src/app/payments/transactions/page.tsx b/apps/playground-web/src/app/payments/transactions/page.tsx
index e95dd0ef130..5c63c63eda7 100644
--- a/apps/playground-web/src/app/payments/transactions/page.tsx
+++ b/apps/playground-web/src/app/payments/transactions/page.tsx
@@ -1,4 +1,4 @@
-import type { Metadata } from "next";
+import { ArrowLeftRightIcon } from "lucide-react";
import { PageLayout } from "@/components/blocks/APIHeader";
import { CodeExample } from "@/components/code/code-example";
import {
@@ -6,28 +6,32 @@ import {
PayTransactionPreview,
} from "@/components/pay/transaction-button";
import ThirdwebProvider from "@/components/thirdweb-provider";
-import { metadataBase } from "@/lib/constants";
+import { createMetadata } from "@/lib/metadata";
-export const metadata: Metadata = {
- description:
- "The easiest way for users to transact in your app. Onramp users in clicks and generate revenue for each user transaction. Integrate for free.",
- metadataBase,
- title: "Integrate Fiat & Cross-Chain Crypto Payments | thirdweb Pay",
-};
+const title = "Onchain Transaction Component";
+const description =
+ "Enable seamless onchain transactions for any contract with fiat or crypto with amounts calculated and automatic execution after funds are confirmed.";
+const ogDescription =
+ "Power onchain transactions with fiat or crypto payments. Automatically calculate costs and run the transaction post onramp or token swap.";
+
+export const metadata = createMetadata({
+ description: ogDescription,
+ title,
+ image: {
+ icon: "payments",
+ title,
+ },
+});
export default function Page() {
return (
- Let your users pay for onchain transactions with fiat or crypto on
- any chain.
- >
- }
+ description={description}
docsLink="https://portal.thirdweb.com/wallets/sponsor-gas?utm_source=playground"
- title="Onchain transactions with fiat or crypto"
+ title={title}
>
diff --git a/apps/playground-web/src/app/payments/ui-components/page.tsx b/apps/playground-web/src/app/payments/ui-components/page.tsx
index 042b99cb31f..7420766a344 100644
--- a/apps/playground-web/src/app/payments/ui-components/page.tsx
+++ b/apps/playground-web/src/app/payments/ui-components/page.tsx
@@ -1,15 +1,23 @@
-import type { Metadata } from "next";
+import { BoxIcon } from "lucide-react";
+import { PageLayout } from "@/components/blocks/APIHeader";
import ThirdwebProvider from "@/components/thirdweb-provider";
-import { metadataBase } from "@/lib/constants";
-import { PageLayout } from "../../../components/blocks/APIHeader";
+import { createMetadata } from "@/lib/metadata";
import PayEmbedPlayground from "../embed/page";
-export const metadata: Metadata = {
- description:
- "The easiest way for users to transact in your app. Onramp users, pay with any token and generate revenue for each user transaction. Integrate for free.",
- metadataBase,
- title: "Integrate Fiat & Cross-Chain Crypto Payments | thirdweb Payments",
-};
+const title = "Crypto Payments UI Components";
+const description =
+ "Onramp, swap, & bridge over 1,000+ tokens to enable seamless crypto payments, checkouts, and transactions";
+const ogDescription =
+ "Onramp, swap, and bridge cryptocurrency with easy to implement components for purchasing crypto, checking out physical or digital goods and services, and executing onchain transactions.";
+
+export const metadata = createMetadata({
+ description: ogDescription,
+ title,
+ image: {
+ icon: "payments",
+ title,
+ },
+});
export default function Page(props: {
searchParams: Promise<{ tab: string }>;
@@ -17,14 +25,10 @@ export default function Page(props: {
return (
- Onramp users with credit card & cross-chain crypto payments —
- and generate revenue for each user transaction.
- >
- }
+ icon={BoxIcon}
+ description={description}
docsLink="https://portal.thirdweb.com/payments?utm_source=playground"
- title="Payments UI component"
+ title={title}
>
diff --git a/apps/playground-web/src/app/token-selector-demo/page.tsx b/apps/playground-web/src/app/token-selector-demo/page.tsx
deleted file mode 100644
index dbeceb2e44d..00000000000
--- a/apps/playground-web/src/app/token-selector-demo/page.tsx
+++ /dev/null
@@ -1,87 +0,0 @@
-"use client";
-
-import { useState } from "react";
-import { arbitrum, base, ethereum } from "thirdweb/chains";
-import { PageLayout } from "@/components/blocks/APIHeader";
-import ThirdwebProvider from "@/components/thirdweb-provider";
-import { TokenSelector } from "@/components/ui/TokenSelector";
-import { THIRDWEB_CLIENT } from "@/lib/client";
-import type { TokenMetadata } from "@/lib/types";
-
-export default function TokenSelectorDemo() {
- const [selectedToken, setSelectedToken] = useState<
- { chainId: number; address: string } | undefined
- >(undefined);
-
- const [selectedChain, setSelectedChain] = useState(ethereum.id);
-
- const chains = [
- { id: ethereum.id, name: "Ethereum" },
- { id: base.id, name: "Base" },
- { id: arbitrum.id, name: "Arbitrum" },
- ];
-
- return (
-
-
-
-
-
- );
-}
diff --git a/apps/playground-web/src/app/wallets/headless/nft-components/page.tsx b/apps/playground-web/src/app/tokens/nft-components/page.tsx
similarity index 53%
rename from apps/playground-web/src/app/wallets/headless/nft-components/page.tsx
rename to apps/playground-web/src/app/tokens/nft-components/page.tsx
index 99145089022..ebd5fb7b42c 100644
--- a/apps/playground-web/src/app/wallets/headless/nft-components/page.tsx
+++ b/apps/playground-web/src/app/tokens/nft-components/page.tsx
@@ -1,4 +1,4 @@
-import type { Metadata } from "next";
+import { ImageIcon } from "lucide-react";
import { PageLayout } from "@/components/blocks/APIHeader";
import {
NftCardExample,
@@ -7,24 +7,29 @@ import {
NftNameExample,
} from "@/components/headless-ui/nft-examples";
import ThirdwebProvider from "@/components/thirdweb-provider";
-import { metadataBase } from "@/lib/constants";
+import { createMetadata } from "@/lib/metadata";
-export const metadata: Metadata = {
- description:
- "Elevate your NFT marketplace with our React headless UI components, engineered for seamless digital asset transactions. These customizable, zero-styling components simplify NFT interactions while giving developers complete freedom to craft their perfect user interface.",
- metadataBase,
- title: "NFT Components",
-};
+const title = "NFT Components";
+const description =
+ "Headless UI components for rendering NFT Media and metadata";
+
+export const metadata = createMetadata({
+ title,
+ description,
+ image: {
+ icon: "wallets",
+ title,
+ },
+});
export default function Page() {
return (
Headless UI components for rendering NFT Media and metadata>
- }
+ icon={ImageIcon}
+ description={description}
docsLink="https://portal.thirdweb.com/react/v5/components/onchain#nfts?utm_source=playground"
- title="NFT Components"
+ title={title}
>
diff --git a/apps/playground-web/src/app/wallets/headless/token-components/page.tsx b/apps/playground-web/src/app/tokens/token-components/page.tsx
similarity index 58%
rename from apps/playground-web/src/app/wallets/headless/token-components/page.tsx
rename to apps/playground-web/src/app/tokens/token-components/page.tsx
index 0ef6505090e..118ca4c7fec 100644
--- a/apps/playground-web/src/app/wallets/headless/token-components/page.tsx
+++ b/apps/playground-web/src/app/tokens/token-components/page.tsx
@@ -1,4 +1,4 @@
-import type { Metadata } from "next";
+import { DollarSignIcon } from "lucide-react";
import { PageLayout } from "@/components/blocks/APIHeader";
import {
TokenImageBasic,
@@ -6,27 +6,30 @@ import {
TokenSymbolBasic,
} from "@/components/headless-ui/token-examples";
import ThirdwebProvider from "@/components/thirdweb-provider";
-import { metadataBase } from "@/lib/constants";
+import { createMetadata } from "@/lib/metadata";
-export const metadata: Metadata = {
- description:
- "Headless UI components for rendering token image, name, and symbol",
- metadataBase,
- title: "Token Components",
-};
+const title = "Token Components";
+const description =
+ "Headless UI components for rendering token image, name, and symbol";
+
+export const metadata = createMetadata({
+ title,
+ description,
+ image: {
+ icon: "wallets",
+ title,
+ },
+});
export default function Page() {
return (
- Headless UI components for rendering token image, name, and symbol
- >
- }
+ icon={DollarSignIcon}
+ description={description}
docsLink="https://portal.thirdweb.com/react/v5/components/onchain#tokens?utm_source=playground"
- title="Token Components"
+ title={title}
>
diff --git a/apps/playground-web/src/app/transactions/airdrop-tokens/page.tsx b/apps/playground-web/src/app/transactions/airdrop-tokens/page.tsx
index 247b1c75f04..7230d65bde8 100644
--- a/apps/playground-web/src/app/transactions/airdrop-tokens/page.tsx
+++ b/apps/playground-web/src/app/transactions/airdrop-tokens/page.tsx
@@ -1,20 +1,33 @@
+import { PlaneIcon } from "lucide-react";
import { EngineAirdropPreview } from "@/app/transactions/airdrop-tokens/_components/airdrop-preview";
+import { PageLayout } from "@/components/blocks/APIHeader";
import ThirdwebProvider from "@/components/thirdweb-provider";
-import { PageLayout } from "../../../components/blocks/APIHeader";
+import { createMetadata } from "@/lib/metadata";
import { AirdropCode } from "./_components/airdrop-code";
+const title = "Airdrop Tokens";
+const description =
+ "Airdrop ERC-20, ERC-721, or ERC-1155 tokens at scale to multiple addresses. Support gas sponsorship and receive real-time status updates for each transaction.";
+const ogDescription =
+ "Airdrop any collection of ERC20, ERC721, or ERC1155 tokens with a few lines of code. Try the flow, inspect the smart contract, and copy code directly into your app.";
+
+export const metadata = createMetadata({
+ description: ogDescription,
+ title,
+ image: {
+ icon: "transactions",
+ title,
+ },
+});
+
export default function Page() {
return (
- Engine makes it effortless for any developer to airdrop tokens at
- scale. You sponsor the gas so your users only need a wallet address!
- >
- }
+ icon={PlaneIcon}
+ description={description}
docsLink="https://thirdweb-engine.apidocumentation.com/reference#tag/erc20/POST/contract/{chain}/{contractAddress}/erc20/mint-batch-to?utm_source=playground"
- title="Airdrop"
+ title={title}
>
diff --git a/apps/playground-web/src/app/transactions/mint-tokens/page.tsx b/apps/playground-web/src/app/transactions/mint-tokens/page.tsx
index 009291364db..febda3cab4b 100644
--- a/apps/playground-web/src/app/transactions/mint-tokens/page.tsx
+++ b/apps/playground-web/src/app/transactions/mint-tokens/page.tsx
@@ -1,20 +1,33 @@
+import { StampIcon } from "lucide-react";
import { EngineMintPreview } from "@/app/transactions/mint-tokens/_components/mint-preview";
+import { PageLayout } from "@/components/blocks/APIHeader";
import ThirdwebProvider from "@/components/thirdweb-provider";
-import { PageLayout } from "../../../components/blocks/APIHeader";
+import { createMetadata } from "@/lib/metadata";
import { MintCode } from "./_components/mint-code";
+const title = "Mint NFTs";
+const description =
+ "Enable users to mint new tokens into any smart contract. Gas fees are sponsored, so users only need to provide a wallet address";
+const ogDescription =
+ "Interactive demo for gasless token minting. Mint tokens to any contract with just a wallet address. Sponsor gas and streamline UX.";
+
+export const metadata = createMetadata({
+ description: ogDescription,
+ title,
+ image: {
+ icon: "transactions",
+ title,
+ },
+});
+
export default function Page() {
return (
- Allow your users to mint new tokens into any given contract. You
- sponsor the gas so your users only need a wallet address!
- >
- }
+ icon={StampIcon}
+ description={description}
docsLink="https://thirdweb-engine.apidocumentation.com/reference#tag/erc1155/POST/contract/{chain}/{contractAddress}/erc1155/mint-to?utm_source=playground"
- title="Mint Dynamic NFTs"
+ title={title}
>
diff --git a/apps/playground-web/src/app/transactions/webhooks/page.tsx b/apps/playground-web/src/app/transactions/webhooks/page.tsx
index 66c458f59e7..02ad2d7a32e 100644
--- a/apps/playground-web/src/app/transactions/webhooks/page.tsx
+++ b/apps/playground-web/src/app/transactions/webhooks/page.tsx
@@ -1,19 +1,32 @@
+import { RssIcon } from "lucide-react";
import { EngineWebhooksPreview } from "@/app/transactions/webhooks/_components/webhooks-preview";
+import { PageLayout } from "@/components/blocks/APIHeader";
import ThirdwebProvider from "@/components/thirdweb-provider";
-import { PageLayout } from "../../../components/blocks/APIHeader";
+import { createMetadata } from "@/lib/metadata";
+
+const title = "Transaction Webhooks";
+const description =
+ "Configure webhooks to notify your backend of transaction events or activity from your server wallet";
+const ogDescription =
+ "Set up webhooks using Transactions to receive real-time notifications for transactions and wallet events. Test the flow and see example payloads in action.";
+
+export const metadata = createMetadata({
+ description: ogDescription,
+ title,
+ image: {
+ icon: "transactions",
+ title,
+ },
+});
export default function Page() {
return (
- Configure webhooks in Engine to notify your backend server of
- transaction or backend wallet events.
- >
- }
+ icon={RssIcon}
+ description={description}
docsLink="https://portal.thirdweb.com/engine/v2/features/webhooks?utm_source=playground"
- title="Webhooks"
+ title={title}
>
diff --git a/apps/playground-web/src/app/wallets/account-abstraction/connect/page.tsx b/apps/playground-web/src/app/wallets/account-abstraction/connect/page.tsx
deleted file mode 100644
index afd5eb2301b..00000000000
--- a/apps/playground-web/src/app/wallets/account-abstraction/connect/page.tsx
+++ /dev/null
@@ -1,91 +0,0 @@
-import type { Metadata } from "next";
-import ThirdwebProvider from "@/components/thirdweb-provider";
-import { metadataBase } from "@/lib/constants";
-import {
- ConnectSmartAccountCustomPreview,
- ConnectSmartAccountPreview,
-} from "../../../../components/account-abstraction/connect-smart-account";
-import { PageLayout } from "../../../../components/blocks/APIHeader";
-import { CodeExample } from "../../../../components/code/code-example";
-
-export const metadata: Metadata = {
- description:
- "Let users sign up with their email, phone number, social media accounts or directly with a wallet. Seamlessly integrate account abstraction and SIWE auth.",
- metadataBase,
- title: "Account Abstraction | thirdweb Connect",
-};
-
-export default function Page() {
- return (
-
-
- Let users connect to their smart accounts with any wallet and unlock
- gas sponsorship, batched transactions, session keys and full wallet
- programmability.
- >
- }
- docsLink="https://portal.thirdweb.com/wallets/sponsor-gas?utm_source=playground"
- title="Connect smart accounts"
- >
-
-
-
- );
-}
-
-function ConnectSmartAccount() {
- return (
- <>
-
-
->);
-};`}
- header={{
- description:
- "Use the prebuilt UI components to connect to smart accounts",
- title: "Using prebuilt UI component",
- }}
- lang="tsx"
- preview={}
- />
-
-
-
- connect(async () => {
- // any wallet connected here will be
- // converted to a smart account
- const adminWallet = inAppWallet();
- await adminWallet.connect({ client, strategy: "google" });
- return adminWallet;
-})}>Connect with Google
->);
-};`}
- header={{
- description: "Build your own UI to connect to smart accounts",
- title: "Build custom UI",
- }}
- lang="tsx"
- preview={}
- />
- >
- );
-}
diff --git a/apps/playground-web/src/app/wallets/auth/page.tsx b/apps/playground-web/src/app/wallets/auth/page.tsx
index 07b57daf2c1..42f7ebb3a47 100644
--- a/apps/playground-web/src/app/wallets/auth/page.tsx
+++ b/apps/playground-web/src/app/wallets/auth/page.tsx
@@ -1,33 +1,34 @@
-import type { Metadata } from "next";
+import { LockIcon } from "lucide-react";
import { BasicAuthPreview } from "@/components/auth/basic-auth";
import { GatedContentPreview } from "@/components/auth/gated-content";
import { SmartAccountAuthPreview } from "@/components/auth/smart-account-auth";
import { CodeExample } from "@/components/code/code-example";
import ThirdwebProvider from "@/components/thirdweb-provider";
-import { metadataBase } from "@/lib/constants";
import { BasicAuthHookPreview } from "../../../components/auth/basic-auth-hook";
import { PageLayout } from "../../../components/blocks/APIHeader";
+import { createMetadata } from "../../../lib/metadata";
-export const metadata: Metadata = {
- description:
- "Authenticate users to your backend using only their wallet. This is a secure and easy way to authenticate users without requiring them to create an additional account.",
- metadataBase,
- title: "Auth | thirdweb Connect",
-};
+const title = "Authentication (SIWE)";
+const description =
+ "Add secure wallet authentication to your app using SIWE and JWT. Authenticate users without passwords via Sign-In with Ethereum and backend token validation";
+
+export const metadata = createMetadata({
+ description,
+ title,
+ image: {
+ icon: "wallets",
+ title,
+ },
+});
export default function Page() {
return (
- Authenticate users to your backend using only their wallet. This is
- a secure and easy way to authenticate users without requiring them
- to create an additional account.
- >
- }
+ icon={LockIcon}
+ title={title}
+ description={description}
docsLink="https://portal.thirdweb.com/typescript/v5/auth?utm_source=playground"
- title="Auth"
>
diff --git a/apps/playground-web/src/app/wallets/blockchain-api/page.tsx b/apps/playground-web/src/app/wallets/blockchain-api/page.tsx
deleted file mode 100644
index 5fca12d0f02..00000000000
--- a/apps/playground-web/src/app/wallets/blockchain-api/page.tsx
+++ /dev/null
@@ -1,241 +0,0 @@
-import type { Metadata } from "next";
-import { ReadContractExtensionPreview } from "@/components/blockchain-api/read-contract-extension";
-import { ReadContractRawPreview } from "@/components/blockchain-api/read-contract-raw";
-import { WatchEventPreview } from "@/components/blockchain-api/watch-event-preview";
-import { WriteContractExtensionPreview } from "@/components/blockchain-api/write-contract-extension";
-import { WriteContractRawPreview } from "@/components/blockchain-api/write-contract-raw";
-import { CodeExample } from "@/components/code/code-example";
-import ThirdwebProvider from "@/components/thirdweb-provider";
-import { metadataBase } from "@/lib/constants";
-import { PageLayout } from "../../../components/blocks/APIHeader";
-
-export const metadata: Metadata = {
- description:
- "Interact with EVM blockchains using thirdweb SDK. Create seamless NFT minting experience. Airdrop tokens to millions of users",
- metadataBase,
- title: "Blockchain API | thirdweb Connect",
-};
-
-export default function Page() {
- return (
-
-
- Performant, reliable and type safe API to read write to any contract
- on any EVM chain through our RPC Edge endpoints.
- >
- }
- docsLink="https://portal.thirdweb.com/typescript/v5?utm_source=playground"
- title="Blockchain API"
- >
-
-
-
-
-
-
-
-
-
-
- );
-}
-
-function ReadContractRaw() {
- return (
-
- );
-}
-`}
- header={{
- description:
- "Read data from any contract or wallet. Type safe functions and hooks without needing full ABIs.",
- title: "Query blockchain data",
- }}
- lang="tsx"
- preview={}
- />
- );
-}
-
-function ReadContractExtension() {
- return (
-
- );
-}
-`}
- header={{
- description:
- "Extensions let you do more with less code. High level functions with simple API that do pre and post processing for all common standards.",
- title: "Prebuilt read extensions",
- }}
- lang="tsx"
- preview={}
- />
- );
-}
-
-function WriteContractExtension() {
- return (
-
- claimTo({
- contract: twCoinContract,
- to: account.address,
- quantity: "10",
- })
- }
- >
- Claim
-
-}
-`}
- header={{
- description:
- "Extensions let you do more with less code. High level functions with simple API that do pre and post processing for all common standards.",
- title: "Prebuilt write extensions",
- }}
- lang="tsx"
- preview={}
- />
- );
-}
-
-function WriteContractRaw() {
- return (
-
- prepareContractCall({
- contract: tw_coin,
- method:
- "function transfer(address to, uint256 value) returns (bool)",
- params: [
- "0x...",
- toUnits("5", 18),
- ],
- })
- }
- >
- Send
-
-}
-`}
- header={{
- description:
- "Send transactions with the connected wallet. Type safe functions and hooks to send contracts call or raw transaction.",
- title: "Write data to blockchain",
- }}
- lang="tsx"
- preview={}
- />
- );
-}
-
-function WatchEvent() {
- return (
- {
- const { from, to, value } = item.args;
- console.log("{from}...{value} USDC...{to}");
- });
-}
-`}
- header={{
- description:
- "Subscribe to any contract event. Auto polling hooks and functions with type safe event extensions for all common standards.",
- title: "Listen to blockchain events",
- }}
- lang="tsx"
- preview={}
- />
- );
-}
diff --git a/apps/playground-web/src/app/wallets/in-app-wallet/ecosystem/page.tsx b/apps/playground-web/src/app/wallets/ecosystem-wallet/page.tsx
similarity index 56%
rename from apps/playground-web/src/app/wallets/in-app-wallet/ecosystem/page.tsx
rename to apps/playground-web/src/app/wallets/ecosystem-wallet/page.tsx
index 04a5be61f82..5a2202de4a1 100644
--- a/apps/playground-web/src/app/wallets/in-app-wallet/ecosystem/page.tsx
+++ b/apps/playground-web/src/app/wallets/ecosystem-wallet/page.tsx
@@ -1,30 +1,32 @@
-import type { Metadata } from "next";
+import { AtomIcon } from "lucide-react";
+import { PageLayout } from "@/components/blocks/APIHeader";
import { CodeExample } from "@/components/code/code-example";
-import { PageLayout } from "../../../../components/blocks/APIHeader";
-import { EcosystemConnectEmbed } from "../../../../components/in-app-wallet/ecosystem";
-import { Profiles } from "../../../../components/in-app-wallet/profile-sections";
-import ThirdwebProvider from "../../../../components/thirdweb-provider";
-import { metadataBase } from "../../../../lib/constants";
+import { EcosystemConnectEmbed } from "@/components/in-app-wallet/ecosystem";
+import { Profiles } from "@/components/in-app-wallet/profile-sections";
+import ThirdwebProvider from "@/components/thirdweb-provider";
+import { createMetadata } from "@/lib/metadata";
-export const metadata: Metadata = {
- description:
- "Build a public or permissioned ecosystem by allowing third party apps and games to connect to the same accounts.",
- metadataBase,
- title: "Build your own Ecosystem | thirdweb",
-};
+const title = "Ecosystem Wallets";
+const description =
+ "Enable global wallet-based identity across apps and games. Create public or permissioned ecosystems where users keep one account everywhere.";
+
+export const metadata = createMetadata({
+ description: description,
+ title,
+ image: {
+ icon: "wallets",
+ title,
+ },
+});
export default function Page() {
return (
- Build a public or permissioned ecosystem by allowing third party
- apps and games to connect to the same accounts.
- >
- }
+ icon={AtomIcon}
+ title={title}
+ description={description}
docsLink="https://portal.thirdweb.com/wallets/ecosystem/set-up?utm_source=playground"
- title="Build your own Ecosystem"
>
diff --git a/apps/playground-web/src/app/wallets/headless/account-components/page.tsx b/apps/playground-web/src/app/wallets/headless/account-components/page.tsx
index c30d19b6a8b..46632e6969b 100644
--- a/apps/playground-web/src/app/wallets/headless/account-components/page.tsx
+++ b/apps/playground-web/src/app/wallets/headless/account-components/page.tsx
@@ -1,4 +1,4 @@
-import type { Metadata } from "next";
+import { CircleUserIcon } from "lucide-react";
import { PageLayout } from "@/components/blocks/APIHeader";
import {
AccountAvatarExample,
@@ -7,27 +7,29 @@ import {
AccountNameExample,
} from "@/components/headless-ui/account-examples";
import ThirdwebProvider from "@/components/thirdweb-provider";
-import { metadataBase } from "@/lib/constants";
+import { createMetadata } from "@/lib/metadata";
-export const metadata: Metadata = {
- description:
- "Headless components for rendering account information like ENS name, ENS avatar, account balance and more",
- metadataBase,
- title: "Account Components",
-};
+const title = "Account Components";
+const description =
+ "Headless components for rendering account information like ENS name, ENS avatar, account balance and more";
+
+export const metadata = createMetadata({
+ title,
+ description,
+ image: {
+ icon: "wallets",
+ title,
+ },
+});
export default function Page() {
return (
- Headless components for rendering account information like ENS name,
- ENS avatar, account balance and more
- >
- }
+ icon={CircleUserIcon}
+ title={title}
+ description={description}
docsLink="https://portal.thirdweb.com/react/v5/components/account?utm_source=playground"
- title="Account Components"
>
diff --git a/apps/playground-web/src/app/wallets/headless/chain-components/page.tsx b/apps/playground-web/src/app/wallets/headless/chain-components/page.tsx
index 8df27db802e..0a82921a4fe 100644
--- a/apps/playground-web/src/app/wallets/headless/chain-components/page.tsx
+++ b/apps/playground-web/src/app/wallets/headless/chain-components/page.tsx
@@ -1,28 +1,33 @@
-import type { Metadata } from "next";
+import { LinkIcon } from "lucide-react";
import { PageLayout } from "@/components/blocks/APIHeader";
import {
ChainIconExample,
ChainNameExample,
} from "@/components/headless-ui/chain-examples";
import ThirdwebProvider from "@/components/thirdweb-provider";
-import { metadataBase } from "@/lib/constants";
+import { createMetadata } from "@/lib/metadata";
-export const metadata: Metadata = {
- description: "Headless UI components for rendering chain name and icon",
- metadataBase,
- title: "Chain Components",
-};
+const title = "Chain Components";
+const description = "Headless UI components for rendering chain name and icon";
+
+export const metadata = createMetadata({
+ title,
+ description,
+ image: {
+ icon: "wallets",
+ title,
+ },
+});
export default function Page() {
return (
Headless UI components for rendering chain name and icon>
- }
+ title={title}
+ description={description}
docsLink="https://portal.thirdweb.com/react/v5/components/onchain#chains?utm_source=playground"
- title="Chain Components"
>
diff --git a/apps/playground-web/src/app/wallets/headless/wallet-components/page.tsx b/apps/playground-web/src/app/wallets/headless/wallet-components/page.tsx
index 64b14767169..eec5ad2fcc4 100644
--- a/apps/playground-web/src/app/wallets/headless/wallet-components/page.tsx
+++ b/apps/playground-web/src/app/wallets/headless/wallet-components/page.tsx
@@ -1,28 +1,33 @@
-import type { Metadata } from "next";
+import { WalletCardsIcon } from "lucide-react";
import { PageLayout } from "@/components/blocks/APIHeader";
import {
WalletIconExample,
WalletNameExample,
} from "@/components/headless-ui/wallet-examples";
import ThirdwebProvider from "@/components/thirdweb-provider";
-import { metadataBase } from "@/lib/constants";
+import { createMetadata } from "@/lib/metadata";
-export const metadata: Metadata = {
- description: "Headless UI components for rendering wallet name and icon",
- metadataBase,
- title: "Wallet Components",
-};
+const title = "Wallet Components";
+const description = "Headless UI components for rendering wallet name and icon";
+
+export const metadata = createMetadata({
+ title,
+ description,
+ image: {
+ icon: "wallets",
+ title,
+ },
+});
export default function Page() {
return (
Headless UI components for rendering wallet name and icon>
- }
+ description={description}
docsLink="https://portal.thirdweb.com/react/v5/connecting-wallets/ui-components?utm_source=playground"
- title="Wallet Components"
+ title={title}
>
diff --git a/apps/playground-web/src/app/wallets/in-app-wallet/page.tsx b/apps/playground-web/src/app/wallets/in-app-wallet/page.tsx
index 3f5e5efe8ea..6bb4590ea1d 100644
--- a/apps/playground-web/src/app/wallets/in-app-wallet/page.tsx
+++ b/apps/playground-web/src/app/wallets/in-app-wallet/page.tsx
@@ -1,33 +1,33 @@
-import type { Metadata } from "next";
+import { UserIcon } from "lucide-react";
import { CodeExample } from "@/components/code/code-example";
import { CustomLoginForm } from "@/components/in-app-wallet/custom-login-form";
+import { createMetadata } from "@/lib/metadata";
import { PageLayout } from "../../../components/blocks/APIHeader";
import { InAppConnectEmbed } from "../../../components/in-app-wallet/connect-button";
import { Profiles } from "../../../components/in-app-wallet/profile-sections";
import ThirdwebProvider from "../../../components/thirdweb-provider";
-import { metadataBase } from "../../../lib/constants";
-export const metadata: Metadata = {
- description:
- "Let users sign up with their email, phone number, social media accounts or directly with a wallet",
- metadataBase,
- title: "Any Auth | thirdweb in-app wallet",
-};
+const title = "In-App Wallets";
+const description =
+ "Add social login, passkey, phone, or email sign-in to your app. Use built-in auth or connect your own backend with custom endpoints.";
+
+export const metadata = createMetadata({
+ description,
+ title,
+ image: {
+ icon: "wallets",
+ title,
+ },
+});
export default function Page() {
return (
- Use any of the built-in auth methods or bring your own.
-
- Supports custom auth endpoints to integrate with your existing user
- base.
- >
- }
+ description={description}
docsLink="https://portal.thirdweb.com/wallets/users?utm_source=playground"
- title="Onboard users to web3 with any auth method"
+ title={title}
+ icon={UserIcon}
>
diff --git a/apps/playground-web/src/app/wallets/in-app-wallet/sponsor/page.tsx b/apps/playground-web/src/app/wallets/in-app-wallet/sponsor/page.tsx
deleted file mode 100644
index 373a00c053b..00000000000
--- a/apps/playground-web/src/app/wallets/in-app-wallet/sponsor/page.tsx
+++ /dev/null
@@ -1,86 +0,0 @@
-import type { Metadata } from "next";
-import { CodeExample } from "@/components/code/code-example";
-import { PageLayout } from "../../../../components/blocks/APIHeader";
-import { SponsoredInAppTxPreview } from "../../../../components/in-app-wallet/sponsored-tx";
-import ThirdwebProvider from "../../../../components/thirdweb-provider";
-import { metadataBase } from "../../../../lib/constants";
-
-export const metadata: Metadata = {
- description:
- "With in-app wallets, users don't need to confirm every transaction. Combine it with smart account flag to cover gas costs for the best UX",
- metadataBase,
- title: "Signless Sponsored Transactions | thirdweb in-app wallet",
-};
-
-export default function Page() {
- return (
-
-
- With in-app wallets, users {"don't"} need to confirm every
- transaction.
-
- Combine it with smart account flag to cover gas costs for the best
- UX.
- >
- }
- docsLink="https://portal.thirdweb.com/wallets/sponsor-gas?utm_source=playground"
- title="Signless Sponsored Transactions"
- >
-
-
-
- );
-}
-
-function SponsoredInAppTx() {
- return (
-
-
-
- {/* signless, sponsored transactions */}
-
- claimTo({
- contract,
- to: "0x123...",
- tokenId: 0n,
- quantity: 1n,
- })
- }
- >
- Mint
-
- >
- );
-}`}
- lang="tsx"
- preview={}
- />
- );
-}
diff --git a/apps/playground-web/src/app/wallets/sign-in/button/RightSection.tsx b/apps/playground-web/src/app/wallets/sign-in/button/RightSection.tsx
index a8267404768..f42ceb37789 100644
--- a/apps/playground-web/src/app/wallets/sign-in/button/RightSection.tsx
+++ b/apps/playground-web/src/app/wallets/sign-in/button/RightSection.tsx
@@ -151,7 +151,7 @@ export function RightSection(props: {
);
return (
-
+
+
+ );
+}
diff --git a/apps/playground-web/src/app/wallets/sign-in/button/page.tsx b/apps/playground-web/src/app/wallets/sign-in/button/page.tsx
index 1178447129b..a2a42e8773d 100644
--- a/apps/playground-web/src/app/wallets/sign-in/button/page.tsx
+++ b/apps/playground-web/src/app/wallets/sign-in/button/page.tsx
@@ -1,90 +1,31 @@
-"use client";
+import { createMetadata } from "@/lib/metadata";
+import { ConnectButtonPage } from "./connect-button-page";
-import { use, useState } from "react";
-import ThirdwebProvider from "@/components/thirdweb-provider";
-import { PageLayout } from "../../../../components/blocks/APIHeader";
-import type { ConnectPlaygroundOptions } from "../components/types";
-import { LeftSection } from "./LeftSection";
-import { RightSection } from "./RightSection";
+const title = "Connect Button";
+const description =
+ "Wallet connection component to enable sign-in to any 500+ EOA (external wallets) or in-app wallets via email, phone number, passkeys, or social logins";
+const ogDescription =
+ "Plug-and-play wallet connect UI with support for 500+ wallets, passkey and social login, ERC-4337 upgrades, gasless flows, and Sign In with Ethereum.";
-const defaultInAppLoginMethods: ConnectPlaygroundOptions["inAppWallet"]["methods"] =
- [
- "google",
- "discord",
- "telegram",
- "farcaster",
- "email",
- "x",
- "passkey",
- "phone",
- ];
-
-// NOTE: Only set the values that are actually the default values used by Connect component
-const defaultConnectOptions: ConnectPlaygroundOptions = {
- buttonLabel: undefined,
- enableAccountAbstraction: false,
- enableAuth: false,
- inAppWallet: {
- enabled: true,
- methods: defaultInAppLoginMethods,
- },
- localeId: "en_US",
- modalSize: "compact",
- modalTitle: undefined,
- modalTitleIcon: undefined,
- privacyPolicyLink: undefined,
- requireApproval: false,
- ShowThirdwebBranding: true,
- termsOfServiceLink: undefined,
- theme: {
- darkColorOverrides: {},
- lightColorOverrides: {},
- type: "dark",
+export const metadata = createMetadata({
+ description: ogDescription,
+ title,
+ image: {
+ icon: "wallets",
+ title,
},
- walletIds: [
- "io.metamask",
- "com.coinbase.wallet",
- "me.rainbow",
- "io.rabby",
- "io.zerion.wallet",
- ],
-};
+});
-export default function Page(props: {
- searchParams: Promise<{ tab: string }>;
+export default async function Page(props: {
+ searchParams: Promise<{ tab: string | undefined | string[] }>;
}) {
- const searchParams = use(props.searchParams);
- const [connectOptions, setConnectOptions] =
- useState(defaultConnectOptions);
+ const searchParams = await props.searchParams;
return (
-
-
- A fully featured wallet connection component that allows to Connect
- to 500+ external wallets, connect via email, phone number, passkey
- or social logins, Convert any wallet to a ERC4337 smart wallet for
- gasless transactions and provides SIWE (Sign In With Ethereum)
- >
- }
- docsLink="https://portal.thirdweb.com/wallets/auth?utm_source=playground"
- title="ConnectButton"
- >
-
-
-
-
-
-
-
-
-
+
);
}
diff --git a/apps/playground-web/src/app/wallets/sign-in/components/CollapsibleSection.tsx b/apps/playground-web/src/app/wallets/sign-in/components/CollapsibleSection.tsx
index de31a2b246f..ad241681cd1 100644
--- a/apps/playground-web/src/app/wallets/sign-in/components/CollapsibleSection.tsx
+++ b/apps/playground-web/src/app/wallets/sign-in/components/CollapsibleSection.tsx
@@ -1,5 +1,5 @@
import { CustomAccordion } from "@/components/ui/CustomAccordion";
-import { cn } from "../../../../lib/utils";
+import { cn } from "@/lib/utils";
export function CollapsibleSection(props: {
children: React.ReactNode;
@@ -10,13 +10,13 @@ export function CollapsibleSection(props: {
}) {
return (
+
{props.title}
diff --git a/apps/playground-web/src/app/wallets/sign-in/embed/page.tsx b/apps/playground-web/src/app/wallets/sign-in/embed/page.tsx
index ed290405ef0..a31f4aa307f 100644
--- a/apps/playground-web/src/app/wallets/sign-in/embed/page.tsx
+++ b/apps/playground-web/src/app/wallets/sign-in/embed/page.tsx
@@ -1,30 +1,33 @@
-import type { Metadata } from "next";
+import { PanelTopIcon } from "lucide-react";
+import { PageLayout } from "@/components/blocks/APIHeader";
import { CodeExample } from "@/components/code/code-example";
import { StyledConnectEmbed } from "@/components/styled-connect-embed";
import ThirdwebProvider from "@/components/thirdweb-provider";
-import { metadataBase } from "@/lib/constants";
-import { PageLayout } from "../../../../components/blocks/APIHeader";
+import { createMetadata } from "@/lib/metadata";
-export const metadata: Metadata = {
- description:
- "Let users sign up with their email, phone number, social media accounts or directly with a wallet. Seamlessly integrate account abstraction and SIWE auth.",
- metadataBase,
- title: "Sign In, Account Abstraction and SIWE Auth | thirdweb ConnectEmbed",
-};
+const title = "Connect Embed";
+const description =
+ "Embeddable wallet component to manage logged in wallet states, view wallet balance, view assets, or buy and receive funds within an application.";
+const ogDescription =
+ "Wallet component to manage logged in wallet, view wallet balance, view assets, or buy and receive funds within an application";
+
+export const metadata = createMetadata({
+ description: ogDescription,
+ title,
+ image: {
+ icon: "wallets",
+ title,
+ },
+});
export default function Page() {
return (
- Create a login experience tailor-made for your app. Add your wallets
- of choice, enable web2 sign-in options and create a modal that fits
- your brand.
- >
- }
+ icon={PanelTopIcon}
+ title={title}
+ description={description}
docsLink="https://portal.thirdweb.com/wallets?utm_source=playground"
- title="ConnectEmbed"
>
diff --git a/apps/playground-web/src/app/wallets/sign-in/headless/page.tsx b/apps/playground-web/src/app/wallets/sign-in/headless/page.tsx
index c3302eb2334..ca8f712790a 100644
--- a/apps/playground-web/src/app/wallets/sign-in/headless/page.tsx
+++ b/apps/playground-web/src/app/wallets/sign-in/headless/page.tsx
@@ -1,31 +1,34 @@
-import type { Metadata } from "next";
+import { SquircleDashedIcon } from "lucide-react";
import { PageLayout } from "@/components/blocks/APIHeader";
import { CodeExample } from "@/components/code/code-example";
import { HooksPreview } from "@/components/sign-in/hooks";
import ThirdwebProvider from "@/components/thirdweb-provider";
-import { metadataBase } from "@/lib/constants";
+import { createMetadata } from "@/lib/metadata";
import { ModalPreview } from "../../../../components/sign-in/modal";
-export const metadata: Metadata = {
- description:
- "Let users sign up with their email, phone number, social media accounts or directly with a wallet. Seamlessly integrate account abstraction and SIWE auth.",
- metadataBase,
- title: "Sign In, Account Abstraction and SIWE Auth | thirdweb Connect",
-};
+const title = "Headless Connect";
+const description =
+ "Create sign-in flow with your choice of wallets and sign-in options built custom to your branding. Use React hooks for full UI control and built-in wallet state management.";
+const ogDescription =
+ "Build a custom login flow with your choice of wallets and sign-in options. Use React hooks for full UI control and built-in wallet state management.";
+
+export const metadata = createMetadata({
+ description: ogDescription,
+ title,
+ image: {
+ icon: "wallets",
+ title,
+ },
+});
export default function Page() {
return (
- Create a login experience tailor-made for your app. Add your wallets
- of choice, enable web2 sign-in options and create a modal that fits
- your brand.
- >
- }
+ icon={SquircleDashedIcon}
+ title={title}
+ description={description}
docsLink="https://portal.thirdweb.com/wallets?utm_source=playground"
- title="Headless"
>
diff --git a/apps/playground-web/src/app/wallets/social/page.tsx b/apps/playground-web/src/app/wallets/social/page.tsx
index ce032bcddf4..24ff246215c 100644
--- a/apps/playground-web/src/app/wallets/social/page.tsx
+++ b/apps/playground-web/src/app/wallets/social/page.tsx
@@ -1,29 +1,33 @@
-import type { Metadata } from "next";
+import { GlobeIcon } from "lucide-react";
+import { PageLayout } from "@/components/blocks/APIHeader";
import { CodeExample } from "@/components/code/code-example";
import { SocialProfiles } from "@/components/social/social-profiles";
import ThirdwebProvider from "@/components/thirdweb-provider";
-import { metadataBase } from "@/lib/constants";
-import { PageLayout } from "../../../components/blocks/APIHeader";
+import { createMetadata } from "@/lib/metadata";
-export const metadata: Metadata = {
- description:
- "Retrieve any user's onchain identity from popular protocols like ENS, Lens, Farcaster, and more.",
- metadataBase,
- title: "Social APIs | thirdweb Connect",
-};
+const title = "Social Profiles";
+const description =
+ "Enhance wallet authentication and context about user profiles with social identity data from ENS, Lens, and Farcaster";
+const ogDescription =
+ "Enhance wallet authentication with social identity data from ENS, Lens, and Farcaster. Gain context-rich profiles on user login.";
+
+export const metadata = createMetadata({
+ description: ogDescription,
+ title,
+ image: {
+ icon: "wallets",
+ title,
+ },
+});
export default function Page() {
return (
- Gain context about your users and their profiles across other apps
- as soon as they sign into your app.
- >
- }
+ icon={GlobeIcon}
+ title={title}
+ description={description}
docsLink="https://portal.thirdweb.com/wallets?utm_source=playground"
- title="Get any user's onchain identity" // TODO: update this once we have Social API docs
>
diff --git a/apps/playground-web/src/components/ThemeToggle.tsx b/apps/playground-web/src/components/ThemeToggle.tsx
new file mode 100644
index 00000000000..24e9a4b3263
--- /dev/null
+++ b/apps/playground-web/src/components/ThemeToggle.tsx
@@ -0,0 +1,37 @@
+"use client";
+
+import { MoonIcon, SunIcon } from "lucide-react";
+import { useTheme } from "next-themes";
+import { ClientOnly } from "@/components/ClientOnly";
+import { Button } from "@/components/ui/button";
+import { Skeleton } from "@/components/ui/skeleton";
+
+export function ThemeToggle() {
+ const { setTheme, theme } = useTheme();
+
+ return (
+