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

# Interstitial Ads

> Guide to implementing interstitial ads in React Native apps.

## Overview

Interstitial ads are ads that cover the entire app screen. They are suitable for natural transition points in the app, such as level transitions in games or content page transitions.

### Features

* Immersive ads covering the full screen
* Maintained until user explicitly closes
* Support for image and video ads
* High visual attention

<Note>
  Use test unit ID in development: `PUBLIC_TEST_UNIT_ID_INTERSTITIAL`
</Note>

***

## Implementation Methods

Adrop React Native SDK provides two ways to implement interstitial ads:

1. **Class Method** - Direct use of AdropInterstitialAd class
2. **Hook Method** - Using useAdropInterstitialAd Hook (Recommended)

***

## AdropInterstitialAd Class

### Constructor

Create an AdropInterstitialAd instance.

```typescript theme={null}
import { AdropInterstitialAd } from 'adrop-ads-react-native'

const interstitialAd = new AdropInterstitialAd(unitId)
```

<ParamField body="unitId" type="string" required>
  Ad unit ID (issued from console)
</ParamField>

### Properties

<ParamField body="isLoaded" type="boolean">
  Returns whether the ad is loaded.

  ```typescript theme={null}
  if (interstitialAd.isLoaded) {
    // Ad can be shown
  }
  ```
</ParamField>

<ParamField body="unitId" type="string">
  Returns the ad unit ID.

  ```typescript theme={null}
  const unitId = interstitialAd.unitId
  ```
</ParamField>

<ParamField body="creativeId" type="string">
  Returns the creative ID of the currently loaded ad.

  ```typescript theme={null}
  const creativeId = interstitialAd.creativeId
  ```
</ParamField>

<ParamField body="txId" type="string">
  Returns the transaction ID of the currently loaded ad.

  ```typescript theme={null}
  const txId = interstitialAd.txId
  ```
</ParamField>

<ParamField body="campaignId" type="string">
  Returns the campaign ID of the currently loaded ad.

  ```typescript theme={null}
  const campaignId = interstitialAd.campaignId
  ```
</ParamField>

<ParamField body="destinationURL" type="string">
  Returns the destination URL of the currently loaded ad.

  ```typescript theme={null}
  const destinationURL = interstitialAd.destinationURL
  ```
</ParamField>

<ParamField body="browserTarget" type="BrowserTarget">
  Returns the browser target setting of the currently loaded ad (`BrowserTarget.EXTERNAL` or `BrowserTarget.INTERNAL`).

  ```typescript theme={null}
  const browserTarget = interstitialAd.browserTarget
  ```
</ParamField>

<ParamField body="listener" type="AdropListener">
  Sets the listener to receive ad events.

  ```typescript theme={null}
  interstitialAd.listener = {
    onAdReceived: (ad) => console.log('Ad received'),
    onAdFailedToReceive: (ad, errorCode) => console.log('Reception failed', errorCode),
    // ... other callbacks
  }
  ```
</ParamField>

### Methods

<ParamField body="load()" type="() => void">
  Requests and loads the ad.

  ```typescript theme={null}
  interstitialAd.load()
  ```
</ParamField>

<ParamField body="show()" type="() => void">
  Shows the loaded ad. Should be called when `isLoaded` is `true`.

  ```typescript theme={null}
  if (interstitialAd.isLoaded) {
    interstitialAd.show()
  }
  ```
</ParamField>

<ParamField body="close()" type="() => void">
  Closes the currently displayed ad. Useful for handling back button press on Android.

  ```typescript theme={null}
  interstitialAd.close()
  ```
</ParamField>

<ParamField body="destroy()" type="() => void">
  Destroys the ad instance and releases resources. Must be called on component unmount.

  ```typescript theme={null}
  useEffect(() => {
    return () => {
      interstitialAd?.destroy()
    }
  }, [interstitialAd])
  ```
</ParamField>

***

## AdropListener Interface

Callback interface for receiving ad events.

### Recommended Callbacks

<ParamField body="onAdReceived" type="(ad: AdropAd) => void">
  Called when ad reception is successful. At this point, you can call `show()` to display the ad.

  ```typescript theme={null}
  onAdReceived: (ad) => {
    console.log('Ad received:', ad.unitId)
    // Ad ready to show
  }
  ```
</ParamField>

<ParamField body="onAdFailedToReceive" type="(ad: AdropAd, errorCode?: string) => void">
  Called when ad reception fails. You can check the failure reason through the error code.

  ```typescript theme={null}
  onAdFailedToReceive: (ad, errorCode) => {
    console.log('Ad reception failed:', errorCode)
  }
  ```
</ParamField>

### Optional Callbacks

<ParamField body="onAdImpression" type="(ad: AdropAd) => void">
  Called when ad impression is recorded.

  ```typescript theme={null}
  onAdImpression: (ad) => {
    console.log('Ad impression recorded')
  }
  ```
</ParamField>

<ParamField body="onAdClicked" type="(ad: AdropAd) => void">
  Called when user clicks the ad.

  ```typescript theme={null}
  onAdClicked: (ad) => {
    console.log('Ad clicked')
  }
  ```
</ParamField>

<ParamField body="onAdWillPresentFullScreen" type="(ad: AdropAd) => void">
  Called just before the full-screen ad is displayed. You can perform actions such as pausing the game.

  ```typescript theme={null}
  onAdWillPresentFullScreen: (ad) => {
    console.log('About to show ad')
    // Pause game, stop music, etc.
  }
  ```
</ParamField>

<ParamField body="onAdDidPresentFullScreen" type="(ad: AdropAd) => void">
  Called immediately after the full-screen ad is displayed.

  ```typescript theme={null}
  onAdDidPresentFullScreen: (ad) => {
    console.log('Ad displayed')
  }
  ```
</ParamField>

<ParamField body="onAdWillDismissFullScreen" type="(ad: AdropAd) => void">
  Called just before the full-screen ad is closed.

  ```typescript theme={null}
  onAdWillDismissFullScreen: (ad) => {
    console.log('About to close ad')
  }
  ```
</ParamField>

<ParamField body="onAdDidDismissFullScreen" type="(ad: AdropAd) => void">
  Called immediately after the full-screen ad is closed. Good time to preload the next ad.

  ```typescript theme={null}
  onAdDidDismissFullScreen: (ad) => {
    console.log('Ad closed')
    // Resume game, load next ad, etc.
  }
  ```
</ParamField>

<ParamField body="onAdFailedToShowFullScreen" type="(ad: AdropAd, errorCode?: string) => void">
  Called when ad display fails. You can check the failure reason through the error code.

  ```typescript theme={null}
  onAdFailedToShowFullScreen: (ad, errorCode) => {
    console.log('Ad display failed:', errorCode)
  }
  ```
</ParamField>

<ParamField body="onAdBackButtonPressed" type="(ad: AdropAd) => void">
  Called when the user presses the back button while the ad is displayed. **Android only.**

  ```typescript theme={null}
  onAdBackButtonPressed: (ad) => {
    console.log('Back button pressed')
  }
  ```
</ParamField>

***

## Class Method Implementation Example

Method using AdropInterstitialAd class directly.

```typescript theme={null}
import React, { useCallback, useEffect, useMemo, useState } from 'react'
import { Button, StyleSheet, Text, View } from 'react-native'
import { AdropInterstitialAd, type AdropListener } from 'adrop-ads-react-native'

const InterstitialAdScreen: React.FC = () => {
  const [interstitialAd, setInterstitialAd] = useState<AdropInterstitialAd>()
  const [isLoaded, setIsLoaded] = useState(false)
  const [errorCode, setErrorCode] = useState('')

  // Set up ad event listener
  const listener: AdropListener = useMemo(() => ({
    onAdReceived: (ad) => {
      console.log('Interstitial ad received:', ad.unitId)
      setIsLoaded(true)
      setErrorCode('')
    },
    onAdFailedToReceive: (ad, error) => {
      console.log('Interstitial ad reception failed:', error)
      setErrorCode(error || 'Unknown error')
      setIsLoaded(false)
    },
    onAdClicked: (ad) => {
      console.log('Interstitial ad clicked')
    },
    onAdImpression: (ad) => {
      console.log('Interstitial ad impression')
    },
    onAdWillPresentFullScreen: (ad) => {
      console.log('About to show interstitial ad')
      // Pause game, stop music, etc.
    },
    onAdDidPresentFullScreen: (ad) => {
      console.log('Interstitial ad displayed')
    },
    onAdWillDismissFullScreen: (ad) => {
      console.log('About to close interstitial ad')
    },
    onAdDidDismissFullScreen: (ad) => {
      console.log('Interstitial ad closed')
      setIsLoaded(false)
      // Resume game, preload next ad, etc.
    },
    onAdFailedToShowFullScreen: (ad, error) => {
      console.log('Interstitial ad display failed:', error)
      setErrorCode(error || 'Unknown error')
      setIsLoaded(false)
    },
    onAdBackButtonPressed: (ad) => {
      console.log('Back button pressed')
      ad.close() // Close ad on back button press (Android only)
    },
  }), [])

  // Initialize ad instance
  useEffect(() => {
    const ad = new AdropInterstitialAd('YOUR_UNIT_ID')
    ad.listener = listener
    setInterstitialAd(ad)

    // Clean up on component unmount
    return () => {
      ad.destroy()
    }
  }, [listener])

  // Load ad
  const loadAd = useCallback(() => {
    interstitialAd?.load()
  }, [interstitialAd])

  // Show ad
  const showAd = useCallback(() => {
    if (interstitialAd?.isLoaded) {
      interstitialAd.show()
    } else {
      console.log('Ad not loaded yet')
    }
  }, [interstitialAd])

  return (
    <View style={styles.container}>
      <Button
        title="Load Ad"
        onPress={loadAd}
      />
      <Button
        title="Show Ad"
        onPress={showAd}
        disabled={!isLoaded}
      />
      {errorCode && (
        <Text style={styles.error}>Error: {errorCode}</Text>
      )}
    </View>
  )
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    gap: 16,
  },
  error: {
    color: 'red',
    marginTop: 16,
  },
})

export default InterstitialAdScreen
```

***

## useAdropInterstitialAd Hook

You can implement interstitial ads more easily using React Hook.

### Hook Usage

```typescript theme={null}
import { useAdropInterstitialAd } from 'adrop-ads-react-native'

const { load, show, reset, isLoaded, isOpened, isClosed, isClicked, errorCode, isReady } = useAdropInterstitialAd(unitId)
```

<ParamField body="unitId" type="string | null" required>
  Ad unit ID. Passing `null` will release the ad.
</ParamField>

### Return Values

<ParamField body="load" type="() => void">
  Loads the ad. Only works when `isReady` is `true`.

  ```typescript theme={null}
  const handleLoad = () => {
    if (isReady) {
      load()
    }
  }
  ```
</ParamField>

<ParamField body="show" type="() => void">
  Shows the loaded ad.

  ```typescript theme={null}
  const handleShow = () => {
    if (isLoaded) {
      show()
    }
  }
  ```
</ParamField>

<ParamField body="reset" type="() => void">
  Resets ad state and creates a new instance.

  ```typescript theme={null}
  const handleReset = () => {
    reset()
  }
  ```
</ParamField>

<ParamField body="isReady" type="boolean">
  Whether the ad instance is ready.
</ParamField>

<ParamField body="isLoaded" type="boolean">
  Whether the ad is successfully loaded.
</ParamField>

<ParamField body="isOpened" type="boolean">
  Whether the ad is displayed on screen.
</ParamField>

<ParamField body="isClosed" type="boolean">
  Whether the ad is closed.
</ParamField>

<ParamField body="isClicked" type="boolean">
  Whether the ad is clicked.
</ParamField>

<ParamField body="errorCode" type="string | undefined">
  Error code occurred during ad loading or display.
</ParamField>

<ParamField body="isBackPressed" type="boolean">
  Whether the back button was pressed while the ad is displayed. **Android only.**
</ParamField>

<ParamField body="browserTarget" type="BrowserTarget | undefined">
  Browser target setting of the loaded ad (`BrowserTarget.EXTERNAL` or `BrowserTarget.INTERNAL`).
</ParamField>

***

## Hook Method Implementation Example

Method using useAdropInterstitialAd Hook (recommended).

```typescript theme={null}
import React, { useCallback, useMemo } from 'react'
import { Button, StyleSheet, Text, View } from 'react-native'
import { useAdropInterstitialAd } from 'adrop-ads-react-native'

const InterstitialAdScreen: React.FC = () => {
  const unitId = 'YOUR_UNIT_ID'

  const {
    load,
    show,
    reset,
    isLoaded,
    isOpened,
    isClosed,
    isClicked,
    errorCode,
    isReady
  } = useAdropInterstitialAd(unitId)

  // Load ad
  const handleLoad = useCallback(() => {
    if (isReady) {
      load()
    }
  }, [isReady, load])

  // Show ad
  const handleShow = useCallback(() => {
    if (isLoaded) {
      show()
    }
  }, [isLoaded, show])

  // Reset ad
  const handleReset = useCallback(() => {
    reset()
  }, [reset])

  return (
    <View style={styles.container}>
      <Button
        title="Load Ad"
        onPress={handleLoad}
        disabled={!isReady}
      />

      <Button
        title="Show Ad"
        onPress={handleShow}
        disabled={!isLoaded}
      />

      <Button
        title="Reset Ad"
        onPress={handleReset}
        disabled={!(isOpened || errorCode)}
      />

      {/* Status display */}
      <View style={styles.statusContainer}>
        <Text>Ready: {isReady ? 'Yes' : 'No'}</Text>
        <Text>Loaded: {isLoaded ? 'Yes' : 'No'}</Text>
        <Text>Opened: {isOpened ? 'Yes' : 'No'}</Text>
        <Text>Closed: {isClosed ? 'Yes' : 'No'}</Text>
        <Text>Clicked: {isClicked ? 'Yes' : 'No'}</Text>
      </View>

      {errorCode && (
        <Text style={styles.error}>Error: {errorCode}</Text>
      )}
    </View>
  )
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    gap: 16,
  },
  statusContainer: {
    marginTop: 24,
    padding: 16,
    backgroundColor: '#f0f0f0',
    borderRadius: 8,
  },
  error: {
    color: 'red',
    marginTop: 16,
  },
})

export default InterstitialAdScreen
```

***

## Test Unit ID

Be sure to use test unit IDs in development and test environments.

```typescript theme={null}
// For testing
const TEST_UNIT_ID = 'PUBLIC_TEST_UNIT_ID_INTERSTITIAL'

// Separate dev/production environments
const unitId = __DEV__
  ? 'PUBLIC_TEST_UNIT_ID_INTERSTITIAL'
  : 'YOUR_PRODUCTION_UNIT_ID'
```

<Warning>
  You must use actual unit IDs in production builds. Revenue from test unit IDs will not be settled.
</Warning>

***

## Error Handling

Errors that may occur during ad loading and display should be handled appropriately.

### Error Codes

| Error Code                   | Description               | Response                           |
| ---------------------------- | ------------------------- | ---------------------------------- |
| `AdropErrorCode.network`     | Network error             | Check network connection and retry |
| `AdropErrorCode.internal`    | Internal error            | Retry or contact support           |
| `AdropErrorCode.initialize`  | SDK initialization failed | Check SDK initialization code      |
| `AdropErrorCode.invalidUnit` | Invalid unit ID           | Check unit ID                      |
| `AdropErrorCode.adNoFill`    | Ad inventory shortage     | Normal, retry later                |
| `AdropErrorCode.adLoading`   | Already loading           | Retry after loading completes      |
| `AdropErrorCode.adEmpty`     | No loaded ad              | Show after loading ad              |
| `AdropErrorCode.adShown`     | Already shown ad          | Need to load new ad                |

### Error Handling Example

```typescript theme={null}
const { load, show, errorCode, isLoaded } = useAdropInterstitialAd(unitId)

useEffect(() => {
  if (errorCode) {
    switch (errorCode) {
      case AdropErrorCode.network:
        console.log('Network error: Check connection')
        // Retry after 30 seconds
        setTimeout(() => load(), 30000)
        break

      case AdropErrorCode.adNoFill:
        console.log('No ads available')
        // Continue without ad
        break

      case AdropErrorCode.invalidUnit:
        console.error('Invalid unit ID')
        break

      default:
        console.log('Ad error:', errorCode)
        break
    }
  }
}, [errorCode, load])
```

***

## Best Practices

### 1. Appropriate Display Timing

Show ads at natural transition points in your app.

```typescript theme={null}
// ✅ Good: Game level transition
const handleLevelComplete = () => {
  saveProgress()
  if (isLoaded) {
    show() // Natural transition point
  }
  navigateToNextLevel()
}

// ✅ Good: After reading content
const handleArticleFinished = () => {
  if (isLoaded) {
    show()
  }
}

// ❌ Bad: During user action
const handleButtonClick = () => {
  show() // Disrupts user experience
  performAction()
}
```

### 2. Preloading

Preload ads to minimize user wait time.

```typescript theme={null}
const InterstitialAdScreen: React.FC = () => {
  const { load, show, isLoaded, isClosed } = useAdropInterstitialAd(unitId)

  // Preload ad on component mount
  useEffect(() => {
    load()
  }, [load])

  // Preload next ad after closing
  useEffect(() => {
    if (isClosed) {
      load()
    }
  }, [isClosed, load])

  return (
    // ...
  )
}
```

### 3. Frequency Limiting

Limit how often ads are shown.

```typescript theme={null}
const InterstitialAdScreen: React.FC = () => {
  const { show, isLoaded } = useAdropInterstitialAd(unitId)
  const [lastShownTime, setLastShownTime] = useState(0)
  const MIN_INTERVAL = 3 * 60 * 1000 // 3 minutes

  const showAdWithFrequencyLimit = useCallback(() => {
    const now = Date.now()
    if (now - lastShownTime < MIN_INTERVAL) {
      console.log('Ad display interval too short')
      return
    }

    if (isLoaded) {
      show()
      setLastShownTime(now)
    }
  }, [isLoaded, show, lastShownTime])

  return (
    // ...
  )
}
```

### 4. Game Pause Handling

Use listeners to manage game state in class method.

```typescript theme={null}
const listener: AdropListener = useMemo(() => ({
  onAdWillPresentFullScreen: (ad) => {
    // Pause game
    pauseGame()
    pauseBackgroundMusic()
  },
  onAdDidDismissFullScreen: (ad) => {
    // Resume game
    resumeGame()
    resumeBackgroundMusic()
  },
}), [])
```

### 5. Memory Management

Always release resources on component unmount.

```typescript theme={null}
// Hook method - automatic management
const { load, show } = useAdropInterstitialAd(unitId)

// Class method - manual cleanup required
useEffect(() => {
  const ad = new AdropInterstitialAd(unitId)
  setInterstitialAd(ad)

  return () => {
    ad.destroy() // Required!
  }
}, [unitId])
```

***

## Platform Considerations

### iOS

* On iOS, ads automatically close when the app goes to background
* `onAdDidDismissFullScreen` callback is called

### Android

* Ads can be closed with the back button on Android
* Hardware acceleration may be required

***

## Backfill Ads

<Info>To use backfill ads, you must have the backfill dependency added to your native platforms (Android/iOS).</Info>

When backfill ads are enabled, the SDK automatically falls back to backfill ads when no direct ad is available. You can handle backfill-specific error codes in the listener.

```tsx theme={null}
interstitialAd.listener = {
  onAdReceived: (ad) => {
    console.log('Ad loaded:', ad.creativeId)
  },
  onAdFailedToReceive: (ad, errorCode) => {
    switch (errorCode) {
      case AdropErrorCode.adNoFill:
        console.log('No direct ad available, requesting backfill...')
        break
      case AdropErrorCode.backfillNoFill:
        console.log('No backfill ad available either')
        break
      default:
        console.log('Ad load failed:', errorCode)
    }
  },
}
```

***

## Next Steps

<CardGroup cols={2}>
  <Card title="Rewarded Ads" href="/sdk/react-native/rewarded">
    Improve user engagement with rewarded ads
  </Card>

  <Card title="Banner Ads" href="/sdk/react-native/banner">
    Implement banner ads
  </Card>

  <Card title="Native Ads" href="/sdk/react-native/native">
    Provide natural ad experience with native ads
  </Card>

  <Card title="Popup Ads" href="/sdk/react-native/popup">
    Implement popup ads
  </Card>
</CardGroup>
