Skip to content

Next.js

Use TokenFlight from a client component. The widget needs the browser DOM, so do not import or initialize it inside a Server Component.

Live projectOpen in StackBlitz

Should you read this?

Read this page if your app uses Next.js App Router or Pages Router.

If you are not using Next.js, start with Getting Started or React Integration.

App Router

Create a client component for the widget. This first example renders the UI and callbacks. Add a wallet adapter before users make crypto payments.

tsx
'use client';

import { useEffect, useRef } from 'react';
import { TokenFlightWidget } from '@tokenflight/swap';

export function PaymentWidget() {
  const containerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!containerRef.current) return;

    const widget = new TokenFlightWidget({
      container: containerRef.current,
      config: {
        theme: 'dark',
        toToken: {
          chainId: 8453,
          address: '0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913',
        },
        tradeType: 'EXACT_OUTPUT',
        amount: '100',
      },
      callbacks: {
        onDepositSuccess: (data) => {
          console.log('Payment complete:', data.orderId);
        },
        onDepositError: (error) => {
          console.error(`[${error.code}] ${error.message}`);
        },
      },
    });

    widget.initialize();
    return () => widget.destroy();
  }, []);

  return <div ref={containerRef} style={{ minHeight: 560 }} />;
}

Use it from a page:

tsx
import { PaymentWidget } from '@/components/PaymentWidget';

export default function PaymentPage() {
  return (
    <main>
      <h1>Payment</h1>
      <PaymentWidget />
    </main>
  );
}

Pages Router

Use next/dynamic with server-side rendering disabled.

tsx
import dynamic from 'next/dynamic';

const PaymentWidget = dynamic(
  () => import('../components/PaymentWidget').then((mod) => mod.PaymentWidget),
  {
    ssr: false,
    loading: () => <div style={{ minHeight: 560 }}>Loading payment widget...</div>,
  },
);

export default function PaymentPage() {
  return (
    <main>
      <h1>Payment</h1>
      <PaymentWidget />
    </main>
  );
}

With wallet connection

If your app already uses wagmi, AppKit, RainbowKit, or ConnectKit, create a wallet adapter and pass it to the widget.

Start here:

Common mistakes

  • Importing @tokenflight/swap from a Server Component.
  • Forgetting 'use client'.
  • Creating the widget before the container exists.
  • Not calling destroy() during cleanup.
  • Mutating config after initialize() instead of recreating the widget.

Next step