Developer Docs / Web React SDK / Ads

Web React In-App Advertising

Initialize ads in a React app, show GrowthCat-managed banners and interstitials, build custom ad UI, and validate rewarded ads server-side.

Ad formats

Banner and interstitial placements, including rewarded formats.

Exports

GrowthCatAdBanner, GrowthCatAdInterstitial, and useAd.

Init order

Initialize GrowthCat once. Ads config is fetched from the SDK bootstrap.

1. Overview

Ads use the same GrowthCat client as referrals. During initialization, GrowthCat fetches the SDK bootstrap and configures the ad service with the returned ads settings.

2. Install

bash
npm install @growthcat/web react react-dom
# or
yarn add @growthcat/web react react-dom

3. Initialize GrowthCat

Call GrowthCat.initialize() before rendering any ad components.

ts
import { GrowthCat } from "@growthcat/web";

GrowthCat.initialize({
  apiKey: "gc_live_your_key_here",
  logsEnabled: process.env.NODE_ENV !== "production",
});

4. Initialize Ads

Ads are initialized by the SDK bootstrap. After GrowthCat.initialize(), the client has access toadsConfig, including whether ads are enabled and the cache TTL.

ts
const client = GrowthCat.shared;

if (client.adsConfig?.adsEnabled) {
  GrowthCat.shared.prefetchAdCatalogs(["home_banner", "level_interstitial"]);
}

await GrowthCat.shared.refreshSDKBootstrap();

6. Interstitial Ads

tsx
import { useState } from "react";
import { GrowthCatAdInterstitial } from "@growthcat/web/react";

export function LevelCompleteScreen() {
  const [showAd, setShowAd] = useState(false);

  return (
    <>
      <button onClick={() => setShowAd(true)}>Continue</button>
      <GrowthCatAdInterstitial
        placementKey="level_complete_interstitial"
        appUserId="user_123"
        isOpen={showAd}
        onDismiss={() => setShowAd(false)}
      />
    </>
  );
}

Rewarded interstitials

Pass appUserId for rewarded ads. Only grant rewards from onReward or after validateAdReward confirms the reward server-side.

7. Custom Ad Rendering

Use useAd() when GrowthCat should select and track the ad, but your app owns the visual design.

tsx
import { useAd } from "@growthcat/web/react";

export function CustomBanner({ placementKey }: { placementKey: string }) {
  const { ad, state, trackEvent } = useAd({ placementKey, trackImpression: true });

  if (state === "loading") return <div style={{ height: 60 }} />;
  if (!ad) return null;

  const { creative } = ad;

  return (
    <button
      onClick={() => {
        trackEvent("click");
        if (creative.destinationUrl) window.open(creative.destinationUrl, "_blank");
      }}
    >
      {creative.publicAssetUrl ? <img src={creative.publicAssetUrl} alt="" /> : null}
      <strong>{creative.headline}</strong>
      <span>{creative.ctaText}</span>
    </button>
  );
}

8. Manual Loading And Events

ts
const ad = await GrowthCat.shared.loadAd({ placementKey: "rewarded_coins" });
if (ad) showWatchAdButton();

GrowthCat.shared.trackAdEvent("impression", ad, {
  format: "banner",
  placementKey: "home_banner",
  appUserId: "user_123",
  sessionId,
});

GrowthCat.shared.trackAdEvent("click", ad, {
  format: "banner",
  placementKey: "home_banner",
  appUserId: "user_123",
});

9. Reward Validation

ts
const response = await GrowthCat.shared.validateAdReward(ad, "user_123", {
  sessionId,
  viewedSeconds: 30,
  completed: true,
});

if (response.rewardValidated) {
  grantCoins(response.reward?.amount ?? 0);
}

Never grant a reward if rewardValidated is false or the validation call throws.

10. Offline Behavior

  • Catalog fetch failures can return a cached entry while the TTL is valid.
  • Tracking events are persisted to localStorage and replayed automatically when the browser comes back online.
  • Reward validation throws when offline, so no reward should be granted.