iExchange
iExchange Developer Docs

React / Next.js Guide

This page walks through a production-grade integration of the iExchange widget in a React (Next.js) app.

1. Create a dedicated hook and include the script

// App.tsx (React 19+)
import { useEffect, useRef } from "react";

const SCRIPT_URL = "https://developers.iexchange.global/widget.js";

export default function useQuickTradeWidget() {
  const widgetRef = useRef<any>(null);

  useEffect(() => {
    // Dynamically load the widget bundle once on mount
    const script = document.createElement("script");
    script.src = SCRIPT_URL;
    script.async = true;
    script.onload = () => {
      // The bundle attaches itself to window.QuickTradeWidget
      const { QuickTradeWidget } = window as any;
      widgetRef.current = QuickTradeWidget.createWidget({
        clientOptions: {
          env: "dev",
          defaultChainId: 84532,
          defaultCurrency: "GHS",
          defaultToken: "USDC",
        },
        themeMode: "light",
        variant: "embedded",
        containerNodeOrSelector: "#iexchange-widget-container",
      });
    };
    document.body.appendChild(script);

    return () => widgetRef.current?.destroy?.();
  }, []);

  return widgetRef.current;
}

2. Opening from anywhere

import { Button } from "@shared/src/components/ui/button";
import { useQuickTradeWidget } from "../lib/useQuickTradeWidget";

export function BuyButton() {
  const widget = useQuickTradeWidget();
  return <Button onClick={() => widget?.open?.()}>Buy Crypto</Button>;
}

3. Subscribing to events

widget?.subscribe("QUICK_TRADE", evt => {
  console.log("Trade completed", evt.data);
});

4. Authentication

The widget starts in read-only mode. When you need the user to sign in, you can use either a viem WalletClient or an EIP-1193 provider:

import { createWalletClient, custom } from "viem";

const walletClient = createWalletClient({
  transport: custom(window.ethereum), // MetaMask, Rabby, etc.
});

// Lazy – sign only when required by the widget
widget?.setWalletClient(walletClient);

// Immediate – prompt signature now
await widget?.authenticate(walletClient);

Or with a raw provider (MetaMask, WalletConnect):

// Inject provider so the widget can request accounts later
await widget?.setProvider(window.ethereum);

// Or authenticate immediately with provider
await widget?.authenticate({ provider: window.ethereum });

Need a deeper dive? See the official

viem Wallet Client docs

For advanced scenarios (wagmi, ethers.js) see the dedicated Wallet Integration guide.

5. Switching chains programmatically

// Switch to Base mainnet (8453) later in your flow
await widget?.switchChain(8453);

// Reset to SDK default (use current defaultChainId)
await widget?.switchChain(null);

Next Steps