Back to dashboard
BannerX

Add the BannerX banner to your mini app

BannerX is a banner-exchange network for World App mini apps. Your app shows other apps' banners and earns 1 credit for every valid 60-second view — each credit pays for one view of your own banner across the network. Follow the steps below to go live.

Before you start
Do this once in the BannerX dashboard before touching any code.
  1. 1Open the dashboard and connect your World ID (Orb verification).
  2. 2Register your mini app: app name + your World App ID (app_…) from the World Developer Portal. The banner opens your app inside World App through a deep link.
  3. 3Upload your banner — 1500×120 recommended, PNG / JPEG / WEBP up to 1 MB.
  4. 4Wait for approval. You receive 100 welcome credits the first time your app is approved.
  5. 5Copy your App ID from the “My apps” list (the copy button next to each app). You'll paste it into the component.
Install the package
In your mini app project, install the BannerX client from npm. Requires React 18+.
npm install bannerx-client@latest

Always installs the latest published version.

Add the component
The component does not handle login — your app is responsible for authentication and must pass a stable user id in viewerId. Without viewerId the banner is not shown. It renders a fixed 60px bar (bottom by default) and adds a spacer so it never covers your content.
import { BannerX } from "bannerx-client";

export default function App() {
  const user = useMyAuth(); // your own login (e.g. MiniKit walletAuth)

  return (
    <>
      {/* the rest of your app */}
      {user && (
        <BannerX
          appId="YOUR_APP_ID"            // from the "My apps" list
          viewerId={user.walletAddress}  // stable user id
        />
      )}
    </>
  );
}
Get viewerId from MiniKit (inside World App)
Use the wallet address from MiniKit walletAuth as a stable viewerId — it's the same across every mini app, so views are counted correctly.
import { MiniKit } from "@worldcoin/minikit-js";

const res = await fetch("/api/nonce");
const { nonce } = await res.json();

const { finalPayload } = await MiniKit.commandsAsync.walletAuth({ nonce });
if (finalPayload.status === "success") {
  setViewerId(finalPayload.address.toLowerCase());
}
Component props
Only appId and viewerId are required.
PropTypeRequiredDescription
appIdstringYesYour App ID registered in BannerX (this is the app that earns credits).
viewerIdstringYesStable id of the user logged in to your app (e.g. wallet address or nullifier hash).
apiUrlstringNoBase URL of the BannerX API. Defaults to the production API — you usually don't need to set it.
position"top" | "bottom"NoPosition of the 60px bar. Defaults to "bottom".
classNamestringNoExtra CSS class on the container.
styleCSSPropertiesNoExtra inline styles on the container.
onExposure(exposureId) => voidNoCalled when a 60s exposure is credited.
onError(error) => voidNoCalled on fetch/report errors.
How it works
  • The component fetches a banner from the network (never your own — your appId is excluded) and counts 60 seconds of visible time, pausing when the tab/app is in the background.
  • At 60s it records the exposure: the banner's app pays 1 credit and your app receives 1 credit. Then it rotates to the next banner.
  • If the network has no banners with credits, it shows the BannerX banner (fallback) — no credits involved.
  • The server enforces a minimum 60s interval per user + banner and checks that the host appId is registered and active. Invalid exposures don't earn credits.
Banner not showing?
  • viewerId is empty — render <BannerX /> only after your user is logged in.
  • Your app isn't approved yet, or it's paused in the dashboard.
  • Wrong App ID — copy it again from the “My apps” list (it's the App ID, not your World App ID).
  • You only see the BannerX fallback banner when there are no other banners with credits to serve — that's expected.