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
npm install @growthcat/web react react-dom
# or
yarn add @growthcat/web react react-dom3. Initialize GrowthCat
Call GrowthCat.initialize() before rendering any ad components.
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.
const client = GrowthCat.shared;
if (client.adsConfig?.adsEnabled) {
GrowthCat.shared.prefetchAdCatalogs(["home_banner", "level_interstitial"]);
}
await GrowthCat.shared.refreshSDKBootstrap();6. Interstitial Ads
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
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.
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
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
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.