> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cloudx.io/llms.txt
> Use this file to discover all available pages before exploring further.

# First Look

> Give CloudX the first chance to fill an ad placement, then fall back to your existing mediation setup

First Look gives CloudX the first chance to fill a placement while preserving your existing mediation setup as the fallback path. Start with one placement, verify load and show behavior, then expand to more placements.

This example uses an AdMob interstitial fallback through [`react-native-google-mobile-ads`](https://docs.page/invertase/react-native-google-mobile-ads). The same pattern applies to other fallback mediators: load CloudX first, load the fallback only if CloudX does not load, and keep the app flow moving when neither source is ready.

<Info>
  Initialize CloudX and Google Mobile Ads before using the hook. Keep your existing pacing, retry, and placement timing rules around it.
</Info>

```tsx useFirstLookInterstitial.ts theme={null}
import { useCallback, useEffect, useRef } from 'react';
import { useInterstitialAd } from 'react-native-google-mobile-ads';
import { useCloudXInterstitial } from 'cloudx-react-native';

export function useFirstLookInterstitial(
  cloudXAdUnitId: string,
  adMobAdUnitId: string,
) {
  const {
    error: cloudXError,
    isLoaded: isCloudXLoaded,
    isLoading: isCloudXLoading,
    load: loadCloudX,
    show: showCloudX,
  } = useCloudXInterstitial(cloudXAdUnitId);
  const {
    error: adMobError,
    isClosed: isAdMobClosed,
    isLoaded: isAdMobLoaded,
    load: loadAdMob,
    show: showAdMob,
  } = useInterstitialAd(adMobAdUnitId);
  const adMobLoadRequested = useRef(false);
  const state = useRef({
    isAdMobLoaded,
    isCloudXLoaded,
    isCloudXLoading,
  });

  state.current = {
    isAdMobLoaded,
    isCloudXLoaded,
    isCloudXLoading,
  };

  useEffect(() => {
    if (
      cloudXError &&
      !isAdMobLoaded &&
      !adMobLoadRequested.current
    ) {
      adMobLoadRequested.current = true;
      loadAdMob();
    }
  }, [cloudXError, isAdMobLoaded, loadAdMob]);

  useEffect(() => {
    if (adMobError || isAdMobClosed) {
      adMobLoadRequested.current = false;
    }
  }, [adMobError, isAdMobClosed]);

  const load = useCallback(() => {
    const current = state.current;

    if (
      current.isCloudXLoading ||
      current.isCloudXLoaded ||
      current.isAdMobLoaded ||
      adMobLoadRequested.current
    ) {
      return;
    }

    loadCloudX();
  }, [loadCloudX]);

  const show = useCallback((): boolean => {
    const current = state.current;

    if (current.isCloudXLoaded) {
      showCloudX();
      return true;
    }

    if (current.isAdMobLoaded) {
      showAdMob();
      return true;
    }

    return false;
  }, [showAdMob, showCloudX]);

  return {
    isReady: isCloudXLoaded || isAdMobLoaded,
    load,
    show,
  };
}
```

Call `load()` when the screen is ready to prepare the placement. At the placement moment, call `show()`. If it returns `false`, neither CloudX nor the fallback had a ready ad, so continue the app flow without showing an ad.

```tsx GameScreen.tsx theme={null}
const firstLookInterstitial = useFirstLookInterstitial(
  CLOUDX_INTERSTITIAL_AD_UNIT_ID,
  ADMOB_INTERSTITIAL_AD_UNIT_ID,
);

useEffect(() => {
  firstLookInterstitial.load();
}, [firstLookInterstitial.load]);

const continueToNextScreen = () => {
  if (!firstLookInterstitial.show()) {
    navigation.navigate('NextScreen');
  }
};
```

After a show, close, or terminal failure, call `load()` again when your app is ready to prepare the next placement opportunity. Both underlying hooks release their event subscriptions when the component unmounts; the CloudX hook also destroys its interstitial instance.

<Tip>
  This sample keeps the fallback lazy: AdMob loads only after CloudX reports an error. Do not parallel-load both sources unless CloudX recommends a different rollout strategy for your app.
</Tip>
