Superbridge
Start typing to search...
You need a Rollie to use the Superbridge Widget.

Integration

Next.js

App Router and Pages Router, with client-only mounting

Next 15 or later, for React 19. Both routers work; the App Router needs one extra hop because a Client Component still prerenders on the server.

npm install @superbridge/widget

App Router

The stylesheet

Import it in the root layout, above your own global CSS. Next emits stylesheets in import order, so this is what puts the widget's variables behind yours.

// app/layout.tsx
import "@superbridge/widget/styles.css";
import "./globals.css";

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  );
}

The widget

'use client' is not enough on its own — client components are still prerendered on the server, and the widget reads browser APIs while it sets up. Load it with next/dynamic and ssr: false.

That call has to happen inside a Client Component; ssr: false from a Server Component is an error in Next 14+. So it's two small files:

// app/bridge/bridge-widget.tsx
"use client";

import { Widget } from "@superbridge/widget";

export default function BridgeWidget() {
  return (
    <Widget
      localDevelopmentApiKey={process.env.NEXT_PUBLIC_WIDGET_DEV_KEY}
    />
  );
}
// app/bridge/bridge.tsx
"use client";

import dynamic from "next/dynamic";

export const Bridge = dynamic(() => import("./bridge-widget"), {
  ssr: false,
  loading: () => <div className="h-[560px] w-full max-w-[540px] mx-auto" />,
});

The loading placeholder is worth setting to roughly the widget's size — without it the page reflows when the widget mounts.

Your page stays a Server Component:

// app/bridge/page.tsx
import { Bridge } from "./bridge";

export default function Page() {
  return (
    <main className="mx-auto max-w-lg py-24">
      <Bridge />
    </main>
  );
}

Pages Router

Same idea, one less file: dynamic() is already being called from a client-side module, so it can live in the page.

// pages/_app.tsx
import "@superbridge/widget/styles.css";
import "../styles/globals.css";

export default function App({ Component, pageProps }) {
  return <Component {...pageProps} />;
}
// pages/bridge.tsx
import dynamic from "next/dynamic";

const Widget = dynamic(
  () => import("@superbridge/widget").then((m) => m.Widget),
  { ssr: false },
);

export default function BridgePage() {
  return (
    <main className="mx-auto max-w-lg py-24">
      <Widget localDevelopmentApiKey={process.env.NEXT_PUBLIC_WIDGET_DEV_KEY} />
    </main>
  );
}

Environment variables

The dev API key has to reach the browser, so it needs the NEXT_PUBLIC_ prefix — which also means it lands in your client bundle. Keep it out of production builds by only defining it in .env.development, or gate it:

<Widget
  localDevelopmentApiKey={
    process.env.NODE_ENV === "development"
      ? process.env.NEXT_PUBLIC_WIDGET_DEV_KEY
      : undefined
  }
/>

In production the widget resolves your Rollie from the domain, so no key is needed. See Local development.

If your app has its own wagmi and the widget behaves as though it isn't there, you have two copies of wagmi installed. Pin one with npm overrides or pnpm pnpm.overrides — see Wallets.

Checklist

  • Next 15+, React 19
  • Widget stylesheet imported above your own in app/layout.tsx or pages/_app.tsx
  • next/dynamic with ssr: false, called from a Client Component
  • Dev key prefixed NEXT_PUBLIC_ and kept out of production