<br />

Rewarded interstitial ads are a full-screen ad format that let you offer in-app
items for ads that appear between screens or game levels. Unlike rewarded ads,
your users don't need to opt in to view the ad. For details,
see

[AdMob case studies](https://admob.google.com/home/resources/freaking-math-powers-revenue-increase-with-google-admob-support/) and
[Overview of rewarded interstitial ad units (Beta)](https://support.google.com/admob/answer/9884467).


To eliminate presentation latency and make sure an ad is available when a
transition occurs, Google Mobile Ads SDK for React Native uses ad preloading to manage background
loading, caching, and buffer replenishment.

This guide shows you how to integrate rewarded interstitial ads with ad
preloading in a React Native app.

## Prerequisites

Before you continue, do the following:

- [Set up Google Mobile Ads SDK for React Native](https://developers.google.com/admob/react-native/quick-start.md.txt).
- [Enable test ads](https://developers.google.com/admob/react-native/test-ads.md.txt) and use the following test ad unit:

### Android

    ca-app-pub-3940256099942544/5354046379

### iOS

    ca-app-pub-3940256099942544/6978759866

## Understand ad preloading

Ad preloading in Google Mobile Ads SDK for React Native automates ad loading and caching.

Ad preloading provides the following benefits:

- **Reference management**: maintains references until ads are shown.
- **Automatic reloading**: loads an ad when one is retrieved from the cache.
- **Managed retries**: loads a new ad when one fails to load.
- **Expiration handling**: refreshes ads before expiring.
- **Cache optimization**: optimizes the cache order to deliver the highest priority ad.

To load ads manually, see
[Load a single rewarded interstitial ad](https://developers.google.com/admob/react-native/rewarded-interstitial/single-load.md.txt).

## Start preloading

To start preloading ads, call the
[`RewardedInterstitialAdPreloader.start`](https://developers.google.com/admob/react-native/reference/class/RewardedInterstitialAdPreloader#RewardedInterstitialAdPreloader.start)
method and pass your `preloadId` value, configuration settings, and event
callbacks to monitor buffer state changes:

```tsx
export function startRewardedInterstitialAdPreloader(
  adUnitId: string,
  preloadId: string,
  customPreloadCallback?: PreloadCallback,
): boolean {
  const started = RewardedInterstitialAdPreloader.start(
    preloadId,
    {
      request: {adUnitId},
      bufferSize: 2,
    },
    {
      // Called when an ad is preloaded into the buffer.
      onAdPreloaded: (event) => {
        console.log(
          `Rewarded interstitial ad preloaded for ${event.preloadId}`,
        );
        customPreloadCallback?.onAdPreloaded?.(event);
      },
      // Called when an ad fails to preload.
      onAdFailedToPreload: (error: LoadAdError) => {
        console.error(
          'Failed to preload rewarded interstitial ad:',
          error.message,
        );
        customPreloadCallback?.onAdFailedToPreload?.(error);
      },
      // Called when all preloaded ads in the buffer have been shown.
      onAdsExhausted: () => {
        console.log('Rewarded interstitial ad buffer exhausted.');
        customPreloadCallback?.onAdsExhausted?.();
      },
    },
  );
  return started;
}
```

`preloadId` is a string that uniquely identifies an ad preloading
configuration. If you use an ad unit ID for a single preloading
configuration in your app, use that ad unit ID as the preload ID. If
your app requires multiple preloaders for the same ad unit ID, pass distinct
strings for each preload ID.

When your app polls a preloaded ad from the buffer, Google Mobile Ads SDK for React Native
requests a replacement ad in the background to refill the buffer. If no
preloaded ads remain in the buffer, Google Mobile Ads SDK for React Native invokes the
[`onAdsExhausted`](https://developers.google.com/admob/react-native/reference/interface/PreloadCallback.md.txt#PreloadCallback.onAdsExhausted) callback.

### Preload cache limits

Google Mobile Ads SDK for React Native enforces an app-wide limit on the total number of preloaded ads:

- Default limit: Google holds a maximum of six preloaded ads in memory. This limit is shared across all formats and preload IDs.
- Recommended buffer: Two preloaded ads for each preload ID.

If your app reaches the app-wide limit, background requests for preloaded
ads pause until existing ads are polled from the cache or destroyed. Preloading
also temporarily pauses while a full-screen ad is actively displayed on screen.

## Poll and show the ad

Before displaying an ad, verify an ad is available by calling the
[`RewardedInterstitialAdPreloader.isAdAvailable`](https://developers.google.com/admob/react-native/reference/class/RewardedInterstitialAdPreloader#RewardedInterstitialAdPreloader.isAdAvailable)
method. To retrieve the ad, call the
[`RewardedInterstitialAdPreloader.pollAd`](https://developers.google.com/admob/react-native/reference/class/RewardedInterstitialAdPreloader#RewardedInterstitialAdPreloader.pollAd)
method.

To show an ad, call the [`show`](https://developers.google.com/admob/react-native/reference/class/RewardedInterstitialAd.md.txt#RewardedInterstitialAd.show) method
with an `onUserEarnedReward` callback to grant the reward when the user finishes
watching the ad. To listen for presentation events, like ad dismissals or
display failures, set the
[`adEventCallback`](https://developers.google.com/admob/react-native/reference/class/RewardedInterstitialAd.md.txt#RewardedInterstitialAd.adEventCallback) property on
the ad instance before calling the `show` method.

The following example checks for ad availability, and listens for full-screen
presentation events before showing the ad:

```tsx
export function showPreloadedRewardedInterstitialAd(
  preloadId: string,
  onRewardEarned: (reward: Reward) => void,
  customAdEventCallback?: FullScreenAdEventCallback,
) {
  if (!RewardedInterstitialAdPreloader.isAdAvailable(preloadId)) {
    console.log('No preloaded rewarded interstitial ad available right now.');
    return;
  }

  const ad = RewardedInterstitialAdPreloader.pollAd(preloadId);
  if (!ad) {
    return;
  }

  ad.adEventCallback = {
    // Called when the ad is presented on screen.
    onAdShowedFullScreenContent: () => {
      console.log(
        'Preloaded rewarded interstitial ad showed full screen content.',
      );
      customAdEventCallback?.onAdShowedFullScreenContent?.();
    },
    // Called when the ad is closed by the user.
    onAdDismissedFullScreenContent: () => {
      console.log(
        'Preloaded rewarded interstitial ad dismissed full screen content.',
      );
      customAdEventCallback?.onAdDismissedFullScreenContent?.();
      ad.destroy();
    },
    // Called when presentation fails.
    onAdFailedToShowFullScreenContent: (error) => {
      console.error(
        'Failed to show preloaded rewarded interstitial ad:',
        error,
      );
      customAdEventCallback?.onAdFailedToShowFullScreenContent?.(error);
      ad.destroy();
    },
    // Called when an impression is recorded.
    onAdImpression: () => {
      console.log('Preloaded rewarded interstitial ad recorded an impression.');
      customAdEventCallback?.onAdImpression?.();
    },
    // Called when the user taps the ad.
    onAdClicked: () => {
      console.log('Preloaded rewarded interstitial ad was clicked.');
      customAdEventCallback?.onAdClicked?.();
    },
    // Called when the ad is estimated to have earned money.
    onAdPaid: (adValue) => {
      console.log(
        `Preloaded rewarded interstitial ad paid: ${adValue.amountMicros}` +
          ` ${adValue.currencyCode}`,
      );
      customAdEventCallback?.onAdPaid?.(adValue);
    },
  };

  ad.show(onRewardEarned);
}
```

To release memory and resources, call the `ad.destroy` method in the
[`onAdDismissedFullScreenContent`](https://developers.google.com/admob/react-native/reference/interface/FullScreenAdEventCallback#FullScreenAdEventCallback.onAdDismissedFullScreenContent)
and
[`onAdFailedToShowFullScreenContent`](https://developers.google.com/admob/react-native/reference/interface/FullScreenAdEventCallback#FullScreenAdEventCallback.onAdFailedToShowFullScreenContent)
callbacks.

## Read the response info

To inspect response info for the next preloaded ad without removing the ad from
the cache, call the
[`RewardedInterstitialAdPreloader.peekAdResponseInfo`](https://developers.google.com/admob/react-native/reference/class/RewardedInterstitialAdPreloader#RewardedInterstitialAdPreloader.peekAdResponseInfo)
method:

```tsx
export function peekRewardedInterstitialAdResponseInfo(
  preloadId: string,
): ResponseInfo | null {
  const responseInfo =
    RewardedInterstitialAdPreloader.peekAdResponseInfo(preloadId);
  if (responseInfo) {
    console.log(
      'Next preloaded rewarded interstitial ad response info:',
      responseInfo,
    );
  }
  return responseInfo;
}
```

If an ad is available, the `peekAdResponseInfo` method returns a
[`ResponseInfo`](https://developers.google.com/admob/react-native/reference/interface/ResponseInfo.md.txt) object containing information about
the loaded ad source and network adapters.

## Optional: Validate SSV callbacks

If your app needs custom verification parameters, such as a user ID or
custom reward metadata, in [server-side verification](https://developers.google.com/admob/react-native/ssv.md.txt) (SSV) callbacks,
set the
[`serverSideVerificationOptions`](https://developers.google.com/admob/react-native/reference/class/RewardedInterstitialAd.md.txt#RewardedInterstitialAd.serverSideVerificationOptions)
property on the polled ad instance before calling the
[`show`](https://developers.google.com/admob/react-native/reference/class/RewardedInterstitialAd.md.txt#RewardedInterstitialAd.show) method.

The values you set are passed to the SSV callback query parameters:

- `userId`: Passes to the `user_id` query parameter to identify the user.
- `customData`: Passes to the `custom_data` query parameter to forward custom metadata.

The following example sets
[`ServerSideVerificationOptions`](https://developers.google.com/admob/react-native/reference/interface/ServerSideVerificationOptions.md.txt)
([`customData`](https://developers.google.com/admob/react-native/reference/interface/ServerSideVerificationOptions.md.txt#ServerSideVerificationOptions.customData) and
[`userId`](https://developers.google.com/admob/react-native/reference/interface/ServerSideVerificationOptions.md.txt#ServerSideVerificationOptions.userId)) on a rewarded
interstitial ad object before showing an ad:

```tsx
export function setServerSideVerificationRewardedInterstitial(
  ad: RewardedInterstitialAd,
) {
  ad.serverSideVerificationOptions = {
    userId: 'user_123',
    customData: 'sample_custom_data',
  };
}
```

> [!IMPORTANT]
> **Key Point:** The `custom_data` query parameter value is [percent-escaped](https://en.wikipedia.org/wiki/Percent-encoding), or URL-encoded. When handling the SSV callback on your server, URL-decode this string before processing.

## Clean up resources

If you no longer need to show ads for a specific preload ID for the rest
of the session, call the
[`RewardedInterstitialAdPreloader.destroy`](https://developers.google.com/admob/react-native/reference/class/RewardedInterstitialAdPreloader#RewardedInterstitialAdPreloader.destroy)
method. This process stops preloading for that preload ID and frees unused
preloaded ads from memory.

The following example stops preloading:

```tsx
export function destroyRewardedInterstitialAdPreloader(preloadId: string) {
  RewardedInterstitialAdPreloader.destroy(preloadId);
}
```

After your user dismisses the ad or the ad fails to show, destroy individual
polled ad instances. For details, see
[Poll and show the ad](https://developers.google.com/admob/react-native/rewarded-interstitial.md.txt#poll_and_show).

## View the full example

This section covers the full implementation of ad preloading.

The following example component starts preloading on mount, tracks available
ad counts, and provides controls to show preloaded rewarded interstitial ads:

```tsx
export function RewardedInterstitialScreen() {
  const [numAdsAvailable, setNumAdsAvailable] = useState<number>(0);
  const [status, setStatus] = useState<string>('Preloader idle.');
  const [reward, setReward] = useState<string | null>(null);

  const refreshAdCount = () => {
    const count =
      RewardedInterstitialAdPreloader.getNumAdsAvailable(PRELOAD_ID);
    setNumAdsAvailable(count);
  };

  useEffect(() => {
    // Start preloading ads on component mount
    const started = startRewardedInterstitialAdPreloader(
      REWARDED_INTERSTITIAL_AD_UNIT_ID,
      PRELOAD_ID,
      {
        onAdPreloaded: () => {
          refreshAdCount();
          setStatus('Rewarded interstitial ad preloaded into buffer.');
        },
        onAdFailedToPreload: (error) => {
          setStatus(
            `Failed to preload rewarded interstitial ad: ${error.message}`,
          );
        },
        onAdsExhausted: () => {
          refreshAdCount();
          setStatus('Preload buffer exhausted for rewarded interstitial ads.');
        },
      },
    );
    if (started) {
      setStatus('Preloader started.');
    }

    // Clean up preloader resources on component unmount
    return () => {
      destroyRewardedInterstitialAdPreloader(PRELOAD_ID);
    };
  }, []);

  const handleShowAd = () => {
    setReward(null);
    setStatus('Showing preloaded ad...');
    showPreloadedRewardedInterstitialAd(
      PRELOAD_ID,
      (userReward) => {
        setReward(`${userReward.amount} ${userReward.type}`);
      },
      {
        onAdDismissedFullScreenContent: () => {
          setStatus('Ad dismissed.');
        },
        onAdFailedToShowFullScreenContent: (error) => {
          setStatus(`Failed to show preloaded ad: ${error.message}`);
        },
      },
    );
    refreshAdCount();
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>Preload Rewarded Interstitial Ads</Text>
      <Text style={styles.status}>Status: {status}</Text>
      <Text style={styles.status}>Ads Available: {numAdsAvailable}</Text>
      {reward && <Text style={styles.rewardText}>Earned: {reward}</Text>}
      <View style={styles.buttonGroup}>
        <Button
          title="Show Preloaded Ad"
          onPress={handleShowAd}
          disabled={numAdsAvailable === 0}
        />
      </View>
    </View>
  );
}
```

## Next steps

After you integrate rewarded interstitial ads, explore the following topics:

- [Impression-level ad revenue](https://developers.google.com/admob/react-native/impression-level-ad-revenue.md.txt)
- [User privacy and consent](https://developers.google.com/admob/react-native/privacy.md.txt)