> ## 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.

# Examples

> Provides various usage examples for the React Native SDK.

## Overview

This document provides practical examples of the Adrop React Native SDK. All examples are written in TypeScript and can be used directly in actual projects.

***

## Sample Project

View the complete sample project on GitHub.

<Card title="React Native Sample Project" icon="github" href="https://github.com/OpenRhapsody/adrop-ads-react-native">
  React Native sample app written in TypeScript
</Card>

***

## Banner Ad Example

A complete example of manually loading banner ads using refs and handling errors.

<CodeGroup>
  ```typescript BannerExample.tsx theme={null}
  import React, { useMemo, useRef, useState } from 'react'
  import {
      Button,
      Dimensions,
      Platform,
      StyleSheet,
      Text,
      View,
  } from 'react-native'
  import { AdropBanner, type AdropBannerMetadata } from 'adrop-ads-react-native'

  interface IBanner {
      load: () => void
  }

  const BannerExample: React.FC = () => {
      const bannerRef = useRef<IBanner>(null)
      const emptyBannerRef = useRef<IBanner>(null)
      const [errorCode, setErrorCode] = useState('')
      const [emptyErrorCode, setEmptyErrorCode] = useState('')

      const unit = useMemo(() => {
          // Use your actual banner ad unit IDs here
          return Platform.OS === 'android'
              ? 'PUBLIC_TEST_UNIT_ID_320_50'
              : 'PUBLIC_TEST_UNIT_ID_320_50'
      }, [])

      const loadBanner = () => {
          bannerRef.current?.load()
          setErrorCode('')
      }

      const loadEmptyBanner = () => {
          emptyBannerRef.current?.load()
          setEmptyErrorCode('')
      }

      const onAdClicked = (unitId: string, metadata?: AdropBannerMetadata) =>
          console.log('banner clicked', unitId, metadata)

      const onAdReceived = (unitId: string, metadata?: AdropBannerMetadata) =>
          console.log('banner received', unitId, metadata)

      const onAdFailedToReceive = (unitId: string, error?: string) => {
          console.log('banner onAdFailedToReceive', unitId, error)
          setErrorCode(error ?? '')
      }

      const onAdImpression = (unitId: string, metadata?: AdropBannerMetadata) =>
          console.log('banner onAdImpression', unitId, metadata)

      const onEmptyAdFailedToReceive = (_: string, error?: string) => {
          console.log('banner onAdFailedToReceive', _, error)
          setEmptyErrorCode(error ?? '')
      }

      const screenWidth = Dimensions.get('window').width

      return (
          <View style={styles.container}>
              <Button title={'Load Banner (Test Ad)'} onPress={loadBanner} />

              <AdropBanner
                  ref={bannerRef}
                  unitId={unit}
                  style={{ ...styles.banner, width: screenWidth }}
                  autoLoad={false}
                  onAdClicked={onAdClicked}
                  onAdReceived={onAdReceived}
                  onAdFailedToReceive={onAdFailedToReceive}
                  onAdImpression={onAdImpression}
              />

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

              <View style={styles.divider} />

              <Button
                  title={'Load Banner (Empty Ad)'}
                  onPress={loadEmptyBanner}
              />

              <AdropBanner
                  ref={emptyBannerRef}
                  unitId={'TEST_UNIT_ID'}
                  style={{ ...styles.banner, width: screenWidth }}
                  autoLoad={false}
                  onAdFailedToReceive={onEmptyAdFailedToReceive}
              />

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

  export default BannerExample

  const styles = StyleSheet.create({
      container: {
          flex: 1,
          alignItems: 'center',
          marginVertical: 50,
          paddingHorizontal: 16,
      },
      banner: {
          width: '100%',
          height: 80,
          marginVertical: 4,
      },
      error: {
          marginVertical: 2,
          color: 'black',
          textAlign: 'center',
      },
      divider: {
          width: '100%',
          height: 1,
          marginVertical: 16,
          backgroundColor: 'black',
      },
  })
  ```
</CodeGroup>

### Key Features

* **Manual Load**: Set `autoLoad={false}` and load ads at desired timing via ref
* **Error Handling**: Manage error state with `onAdFailedToReceive` callback
* **Multiple Banners**: Manage multiple banners independently
* **Platform Support**: Set platform-specific unit IDs using `Platform.OS`

***

## Native Ad Example

An example of using native ads with WebView and handling backfill ads.

<CodeGroup>
  ```typescript NativeAdExample.tsx theme={null}
  import React, { useCallback, useEffect, useMemo, useState } from 'react'
  import {
      AdropBodyView,
      AdropHeadLineView,
      AdropMediaView,
      AdropNativeAd,
      AdropNativeAdView,
      AdropProfileLogoView,
      AdropProfileNameView,
  } from 'adrop-ads-react-native'
  import { WebView } from 'react-native-webview'
  import {
      Button,
      Dimensions,
      ScrollView,
      StyleSheet,
      Text,
      View,
      Linking,
      Platform,
  } from 'react-native'
  import type { AdropNativeAdListener } from 'adrop-ads-react-native'

  const NativeAdExample: React.FC = () => {
      const [nativeAd, setNativeAd] = useState<AdropNativeAd>()
      const [isLoaded, setIsLoaded] = useState(false)
      const [errorCode, setErrorCode] = useState('')

      const disabledReset = !errorCode

      const unit = useMemo(() => {
          return Platform.OS === 'android'
              ? 'PUBLIC_TEST_UNIT_ID_NATIVE'
              : 'PUBLIC_TEST_UNIT_ID_NATIVE'
      }, [])

      const openUrl = useCallback((url: string) => {
          Linking.openURL(url).catch((err) =>
              console.error('Failed to open URL:', err)
          )
      }, [])

      const listener = useMemo(
          (): AdropNativeAdListener => ({
              onAdReceived: (ad) => {
                  console.log(
                      `nativeAd received ${ad.unitId}`,
                      ad.properties,
                      ad.txId,
                      ad.campaignId,
                      ad.creativeId
                  )
                  setIsLoaded(true)
                  setErrorCode('')
              },
              onAdFailedToReceive: (_, error) => {
                  console.log('nativeAd onAdFailedToReceive', error)
                  setErrorCode(error)
              },
              onAdClicked: (ad) => console.log(`nativeAd clicked ${ad.unitId}`),
              onAdImpression: (ad) =>
                  console.log(`nativeAd impressed ${ad.unitId}`),
          }),
          []
      )

      const initialize = useCallback(
          (unitId: string) => {
              let adropNativeAd = new AdropNativeAd(unitId)
              adropNativeAd.listener = listener
              setNativeAd((prev) => {
                  prev?.destroy()
                  return adropNativeAd
              })
              setIsLoaded(false)
              setErrorCode('')
          },
          [listener]
      )

      useEffect(() => {
          initialize(unit)
      }, [initialize, unit])

      const load = () => nativeAd?.load()

      const resetTestAd = () => {
          initialize(unit)
      }

      const resetEmptyAd = () => {
          initialize('TEST_UNIT_ID')
      }

      const adView = useMemo(() => {
          if (!isLoaded) return null

          return (
              <AdropNativeAdView
                  nativeAd={nativeAd}
                  style={{
                      ...styles.adContainer,
                      width: Dimensions.get('window').width,
                  }}
              >
                  <View style={styles.rowContainer}>
                      <AdropProfileLogoView style={styles.icon} />
                      <AdropProfileNameView style={styles.name} />
                  </View>

                  <AdropHeadLineView style={styles.headline} />
                  <AdropBodyView style={styles.body} />

                  {!nativeAd?.isVideoAd || nativeAd?.isBackfilled ? (
                      <AdropMediaView style={styles.adStyle} />
                  ) : (
                      <WebView
                          source={{
                              html: nativeAd?.properties?.creative ?? '',
                          }}
                          style={styles.adStyle}
                          javaScriptEnabled={true}
                          mediaPlaybackRequiresUserAction={false}
                          allowsInlineMediaPlayback={true}
                          scrollEnabled={false}
                          onNavigationStateChange={(event) => {
                              // Android webview event
                              if (
                                  event.url &&
                                  event.url !== 'about:blank' &&
                                  !event.url.startsWith('data:')
                              ) {
                                  openUrl(event.url)
                              }
                          }}
                          onOpenWindow={(event) => {
                              // iOS webview event (window.open)
                              if (event.nativeEvent?.targetUrl) {
                                  openUrl(event.nativeEvent.targetUrl)
                              }
                          }}
                      />
                  )}
              </AdropNativeAdView>
          )
      }, [isLoaded, nativeAd, openUrl])

      return (
          <ScrollView>
              <View style={styles.container}>
                  <View style={styles.button}>
                      <Button title={'Load Native Ad'} onPress={load} />
                  </View>
                  <View style={styles.button}>
                      <Button
                          disabled={disabledReset}
                          title={'Initialize Native Ad (Test Ad)'}
                          onPress={resetTestAd}
                      />
                  </View>
                  {adView}
                  <Text style={styles.description}>
                      After initializing the native ad, click the load button to display the ad.
                  </Text>
                  <View style={styles.button}>
                      <Button
                          disabled={disabledReset}
                          title={'Initialize Native Ad (Empty Ad)'}
                          onPress={resetEmptyAd}
                      />
                  </View>
                  <Text style={styles.description}>
                      After initializing the native ad, click the load button to trigger the error callback.
                  </Text>
                  {errorCode && (
                      <Text style={styles.error}>Error Code: {errorCode}</Text>
                  )}
              </View>
          </ScrollView>
      )
  }

  export default NativeAdExample

  const styles = StyleSheet.create({
      container: {
          flex: 1,
          alignItems: 'center',
          paddingVertical: 5,
          paddingHorizontal: 66,
      },
      button: {
          marginVertical: 4,
      },
      description: {
          color: 'black',
          marginBottom: 24,
          paddingHorizontal: 16,
          textAlign: 'center',
      },
      error: {
          color: 'black',
          marginVertical: 2,
      },
      adContainer: {
          paddingHorizontal: 16,
      },
      adStyle: {
          width: '100%',
          height: 360,
          marginBottom: 24,
      },
      icon: {
          width: 32,
          height: 32,
          marginRight: 8,
      },
      name: {
          fontSize: 14,
          fontWeight: 'bold',
          color: 'black',
      },
      headline: {
          fontSize: 16,
          fontWeight: 'bold',
          color: 'black',
      },
      body: {
          fontSize: 14,
          color: 'black',
          marginVertical: 16,
      },
      rowContainer: {
          display: 'flex',
          flexDirection: 'row',
          justifyContent: 'flex-start',
          alignItems: 'center',
          marginBottom: 8,
      },
  })
  ```
</CodeGroup>

### Key Features

* **Profile Information Display**: Show advertiser information using `AdropProfileLogoView` and `AdropProfileNameView`
* **WebView Integration**: Render HTML creatives with WebView
* **Backfill Handling**: Handle backfill ads using `isBackfilled` property
* **URL Handling**: Process WebView navigation events to open external links
* **Memory Management**: Clean up ad objects with `destroy()` method

***

## Interstitial Ad Example

An example of implementing interstitial ads using Hooks.

<CodeGroup>
  ```typescript InterstitialAdExample.tsx theme={null}
  import React, { useCallback, useMemo, useState } from 'react'
  import { Button, Platform, StyleSheet, Text, View } from 'react-native'
  import { useAdropInterstitialAd } from 'adrop-ads-react-native'

  const InterstitialAdExample: React.FC = () => {
      const unit = useMemo(() => {
          return Platform.OS === 'android'
              ? 'PUBLIC_TEST_UNIT_ID_INTERSTITIAL'
              : 'PUBLIC_TEST_UNIT_ID_INTERSTITIAL'
      }, [])

      const [unitId, setUnitId] = useState(unit)

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

      const disabledReset = !(isOpened || errorCode)

      const loadAd = useCallback(() => {
          if (isReady) {
              load()
          }
      }, [isReady, load])

      const resetTestAd = useCallback(() => {
          reset()
          setUnitId(unit)
      }, [reset, unit])

      const resetEmptyAd = useCallback(() => {
          reset()
          setUnitId('TEST_UNIT_ID')
      }, [reset])

      return (
          <View style={styles.container}>
              <View style={styles.button}>
                  <Button title={'Load Interstitial Ad'} onPress={loadAd} />
              </View>
              <View style={styles.button}>
                  <Button
                      disabled={!isLoaded}
                      title={'Show Interstitial Ad'}
                      onPress={show}
                  />
              </View>
              <View style={styles.button}>
                  <Button
                      disabled={disabledReset}
                      title={'Initialize Interstitial Ad (Test Ad)'}
                      onPress={resetTestAd}
                  />
              </View>
              <Text style={styles.description}>
                  After initializing the interstitial ad, click the load button to load the ad.
              </Text>
              <View style={styles.button}>
                  <Button
                      disabled={disabledReset}
                      title={'Initialize Interstitial Ad (Empty Ad)'}
                      onPress={resetEmptyAd}
                  />
              </View>
              <Text style={styles.description}>
                  After initializing the interstitial ad, click the load button to trigger the error callback.
              </Text>
              {errorCode && (
                  <Text style={styles.error}>Error Code: {errorCode}</Text>
              )}
          </View>
      )
  }

  export default InterstitialAdExample

  const styles = StyleSheet.create({
      container: {
          flex: 1,
          alignItems: 'center',
          marginVertical: 50,
      },
      button: {
          marginVertical: 4,
      },
      description: {
          color: 'black',
          marginBottom: 24,
          paddingHorizontal: 16,
          textAlign: 'center',
      },
      error: {
          color: 'black',
          marginVertical: 2,
      },
  })
  ```
</CodeGroup>

### Key Features

* **Hook Usage**: Easy state management with `useAdropInterstitialAd` Hook
* **State Tracking**: Track ad state using `isLoaded`, `isOpened`, `isReady` states
* **Error Handling**: Check error state with `errorCode`
* **Initialization**: Initialize ads with `reset()` method

<Note>
  Since interstitial ads cover the entire screen, it's important to display them at appropriate times considering user experience.
</Note>

***

## Rewarded Ad Example

An example of implementing rewarded ads using Hooks.

<CodeGroup>
  ```typescript RewardedAdExample.tsx theme={null}
  import React, { useCallback, useMemo, useState } from 'react'
  import { Button, Platform, StyleSheet, Text, View } from 'react-native'
  import { useAdropRewardedAd } from 'adrop-ads-react-native'

  const RewardedAdExample: React.FC = () => {
      const unit = useMemo(() => {
          return Platform.OS === 'android'
              ? 'PUBLIC_TEST_UNIT_ID_REWARDED'
              : 'PUBLIC_TEST_UNIT_ID_REWARDED'
      }, [])

      const [unitId, setUnitId] = useState(unit)

      const { load, show, errorCode, reset, isLoaded, isOpened, isReady } =
          useAdropRewardedAd(unitId)

      const disabledReset = !(isOpened || errorCode)

      const loadAd = useCallback(() => {
          if (isReady) {
              load()
          }
      }, [isReady, load])

      const resetTestAd = useCallback(() => {
          reset()
          setUnitId(unit)
      }, [reset, unit])

      const resetEmptyAd = useCallback(() => {
          reset()
          setUnitId('TEST_UNIT_ID')
      }, [reset])

      return (
          <View style={styles.container}>
              <View style={styles.button}>
                  <Button title={'Load Rewarded Ad'} onPress={loadAd} />
              </View>
              <View style={styles.button}>
                  <Button
                      disabled={!isLoaded}
                      title={'Show Rewarded Ad'}
                      onPress={show}
                  />
              </View>
              <View style={styles.button}>
                  <Button
                      disabled={disabledReset}
                      title={'Initialize Rewarded Ad (Test Ad)'}
                      onPress={resetTestAd}
                  />
              </View>
              <Text style={styles.description}>
                  After initializing the rewarded ad, click the load button to load the ad.
              </Text>
              <View style={styles.button}>
                  <Button
                      disabled={disabledReset}
                      title={'Initialize Rewarded Ad (Empty Ad)'}
                      onPress={resetEmptyAd}
                  />
              </View>
              <Text style={styles.description}>
                  After initializing the rewarded ad, click the load button to trigger the error callback.
              </Text>
              {errorCode && (
                  <Text style={styles.error}>Error Code: {errorCode}</Text>
              )}
          </View>
      )
  }

  export default RewardedAdExample

  const styles = StyleSheet.create({
      container: {
          flex: 1,
          alignItems: 'center',
          marginVertical: 50,
      },
      button: {
          marginVertical: 4,
      },
      description: {
          color: 'black',
          marginBottom: 24,
          paddingHorizontal: 16,
          textAlign: 'center',
      },
      error: {
          color: 'black',
          marginVertical: 2,
      },
  })
  ```
</CodeGroup>

### Key Features

* **Hook Usage**: Easy state management with `useAdropRewardedAd` Hook
* **Reward Handling**: Check reward timing via listener (see [Rewarded Ad Guide](/sdk/react-native/rewarded) for listener setup)
* **State Management**: Check ad state with `isLoaded`, `isOpened`, `isReady`

<Warning>
  Rewarded ads require users to watch the entire ad to receive rewards. Only grant rewards in the `onAdEarnRewardHandler` callback.
</Warning>

***

## Popup Ad Example

An example of implementing and customizing popup ads using classes.

<CodeGroup>
  ```typescript PopupAdExample.tsx theme={null}
  import React, { useCallback, useEffect, useMemo, useState } from 'react'
  import { Button, Platform, StyleSheet, Text, View } from 'react-native'
  import {
      type AdropListener,
      AdropPopupAd,
      type AdropPopupAdColors,
  } from 'adrop-ads-react-native'

  const PopupAdExample: React.FC = () => {
      const [popupAd, setPopupAd] = useState<AdropPopupAd>()
      const [isLoaded, setIsLoaded] = useState(false)
      const [isShown, setIsShown] = useState(false)
      const [errorCode, setErrorCode] = useState('')

      const disabledReset = !(errorCode || isShown)

      const unit = useMemo(() => {
          return Platform.OS === 'android'
              ? 'PUBLIC_TEST_UNIT_ID_POPUP_BOTTOM'
              : 'PUBLIC_TEST_UNIT_ID_POPUP_BOTTOM'
      }, [])

      const listener: AdropListener = useMemo(() => {
          return {
              onAdImpression: (ad: AdropPopupAd) =>
                  console.log(
                      `popup impressed: ${ad.unitId}, ${ad.creativeId}, ${
                          ad.txId
                      }, ${ad.campaignId} ${ad.destinationURL}`
                  ),
              onAdClicked: (ad: AdropPopupAd) => {
                  console.log(
                      `popup clicked: ${ad.unitId}, ${ad.destinationURL}`
                  )
                  ad.close()
              },
              onAdReceived: (ad: AdropPopupAd) => {
                  setIsLoaded(true)
                  console.log(`popup received: ${ad.unitId}`)
                  setErrorCode('')
              },
              onAdFailedToReceive: (_: AdropPopupAd, error: any) => {
                  console.log('popup onAdFailedToReceive', error)
                  setErrorCode(error)
              },
              onAdDidDismissFullScreen: (ad: AdropPopupAd) =>
                  console.log(`popup dismissed: ${ad.unitId}`),
              onAdDidPresentFullScreen: (ad: AdropPopupAd) =>
                  console.log(`popup presented: ${ad.unitId}`),
              onAdFailedToShowFullScreen: (_: AdropPopupAd, error: any) =>
                  setErrorCode(error),
          } as AdropListener
      }, [])

      useEffect(() => {
          return () => {
              popupAd?.destroy()
          }
      }, [popupAd])

      const initialize = useCallback(
          (unitId: string) => {
              // Customize popup ad colors
              let hideForTodayTextColor = '#456'
              let backgroundColor = 'rgba(53, 255, 63, 0.3)'
              let customColors: AdropPopupAdColors = {
                  hideForTodayTextColor,
                  backgroundColor,
              }

              let adropPopupAd = new AdropPopupAd(unitId, customColors)
              adropPopupAd.listener = listener
              setPopupAd((prev) => {
                  prev?.destroy()
                  return adropPopupAd
              })
          },
          [listener]
      )

      useEffect(() => {
          initialize(unit)
      }, [initialize, unit])

      const load = () => popupAd?.load()
      const show = () => {
          popupAd?.show()
          setIsShown(true)
      }
      const resetTestAd = () => {
          initialize(unit)
          resetState()
      }

      const resetEmptyAd = () => {
          initialize('TEST_UNIT_ID')
          resetState()
      }

      const resetState = () => {
          setIsLoaded(false)
          setIsShown(false)
          setErrorCode('')
      }

      return (
          <View style={styles.container}>
              <View style={styles.button}>
                  <Button title={'Load Popup Ad'} onPress={load} />
              </View>
              <View style={styles.button}>
                  <Button
                      disabled={!isLoaded}
                      title={'Show Popup Ad'}
                      onPress={show}
                  />
              </View>
              <View style={styles.button}>
                  <Button
                      disabled={disabledReset}
                      title={'Initialize Popup Ad (Test Ad)'}
                      onPress={resetTestAd}
                  />
              </View>
              <Text style={styles.description}>
                  After initializing the popup ad, click the load button to load the ad.
              </Text>
              <View style={styles.button}>
                  <Button
                      disabled={disabledReset}
                      title={'Initialize Popup Ad (Empty Ad)'}
                      onPress={resetEmptyAd}
                  />
              </View>
              <Text style={styles.description}>
                  After initializing the popup ad, click the load button to trigger the error callback.
              </Text>
              {errorCode && (
                  <Text style={styles.error}>Error Code: {errorCode}</Text>
              )}
          </View>
      )
  }

  export default PopupAdExample

  const styles = StyleSheet.create({
      container: {
          flex: 1,
          alignItems: 'center',
          marginVertical: 50,
      },
      button: {
          marginVertical: 4,
      },
      description: {
          color: 'black',
          marginBottom: 24,
          paddingHorizontal: 16,
          textAlign: 'center',
      },
      error: {
          color: 'black',
          marginVertical: 2,
      },
  })
  ```
</CodeGroup>

### Key Features

* **Class-based**: Direct use of `AdropPopupAd` class
* **Color Customization**: Set popup style with `AdropPopupAdColors`
* **Close on Click**: Call `ad.close()` in `onAdClicked`
* **Memory Management**: Call `destroy()` in `useEffect` cleanup

***

## Targeting Configuration Example

An example of setting ad targeting.

<CodeGroup>
  ```typescript TargetingExample.tsx theme={null}
  import React, { useEffect } from 'react'
  import { View } from 'react-native'
  import { AdropMetrics, AdropProperties, AdropGender } from 'adrop-ads-react-native'

  const TargetingExample: React.FC = () => {
      useEffect(() => {
          // Set user gender
          AdropMetrics.setProperty(AdropProperties.GENDER, AdropGender.MALE)

          // Set user age
          AdropMetrics.setProperty(AdropProperties.AGE, 25)

          // Set user birth date
          AdropMetrics.setProperty(AdropProperties.BIRTH, '19980520')

          // Set custom property (string)
          AdropMetrics.setProperty('customKey', 'customValue')

          // Set custom property (number)
          AdropMetrics.setProperty('level', 10)

          // Set custom property (boolean)
          AdropMetrics.setProperty('isPremium', true)

          // Send event
          AdropMetrics.sendEvent('purchase', {
              item_id: 'SKU-001',
              price: 29900,
              currency: 'KRW',
          })
      }, [])

      return <View />
  }

  export default TargetingExample
  ```
</CodeGroup>

### Available Targeting Properties

| Property                 | Type                          | Description                                        |
| ------------------------ | ----------------------------- | -------------------------------------------------- |
| `AdropProperties.GENDER` | `AdropGender`                 | User gender (`MALE`, `FEMALE`, `OTHER`, `UNKNOWN`) |
| `AdropProperties.AGE`    | `number`                      | User age                                           |
| `AdropProperties.BIRTH`  | `string`                      | User date of birth (yyyyMMdd)                      |
| Custom key               | `string \| number \| boolean` | Custom properties defined by the app               |

<Note>
  Targeting properties are sent to the server during ad requests to display more relevant ads.
</Note>

***

## Error Handling Utility

A utility example that converts error codes into human-readable messages.

<CodeGroup>
  ```typescript ErrorUtils.ts theme={null}
  import { AdropErrorCode } from 'adrop-ads-react-native'

  export const descriptionOf = (errorCode: string): string => {
      switch (errorCode) {
          case AdropErrorCode.network:
              return 'Network connection is unstable'
          case AdropErrorCode.internal:
              return 'An SDK internal error occurred'
          case AdropErrorCode.initialize:
              return 'Adrop must be initialized first'
          case AdropErrorCode.invalidUnit:
              return 'Ad unit ID is invalid'
          case AdropErrorCode.notTargetCountry:
              return 'SDK cannot be used in unsupported countries'
          case AdropErrorCode.inactive:
              return 'No active ad campaigns available'
          case AdropErrorCode.adNoFill:
              return 'No ads matching the criteria. Please try again'
          case AdropErrorCode.adDuplicated:
              return 'Cannot reload after ad has been received'
          case AdropErrorCode.adLoading:
              return 'Waiting for server response after ad request'
          case AdropErrorCode.adEmpty:
              return 'No ad received'
          case AdropErrorCode.adShown:
              return 'This ad has already been shown'
          case AdropErrorCode.adHideForToday:
              return 'Cannot load more today'
          case AdropErrorCode.adLandscapeUnsupported:
              return 'Ads cannot be displayed in landscape mode'
          case AdropErrorCode.backfillNoFill:
              return 'No backfill ad available'
          case AdropErrorCode.undefined:
              return 'Undefined error'
          default:
              return ''
      }
  }
  ```

  ```typescript Usage Example theme={null}
  import { descriptionOf } from './ErrorUtils'

  const handleAdFailedToReceive = (unitId: string, errorCode?: string) => {
      if (errorCode) {
          const errorMessage = descriptionOf(errorCode)
          console.log('Error:', errorMessage)
          Alert.alert('Ad Load Failed', errorMessage)
      }
  }
  ```
</CodeGroup>

### Error Code List

| Error Code               | Description                  |
| ------------------------ | ---------------------------- |
| `network`                | Network connection issue     |
| `internal`               | SDK internal error           |
| `initialize`             | SDK initialization required  |
| `invalidUnit`            | Invalid unit ID              |
| `notTargetCountry`       | Unsupported country          |
| `inactive`               | No active campaigns          |
| `adNoFill`               | No ads available             |
| `adDuplicated`           | Duplicate load attempt       |
| `adLoading`              | Ad loading in progress       |
| `adEmpty`                | Ad not received              |
| `adShown`                | Ad already shown             |
| `adHideForToday`         | "Don't show today" selected  |
| `adLandscapeUnsupported` | Landscape mode not supported |
| `backfillNoFill`         | No backfill ad available     |

***

## Full Integration Example

An example of using all ad formats in a single app.

<CodeGroup>
  ```typescript App.tsx theme={null}
  import React, { useEffect } from 'react'
  import { NavigationContainer } from '@react-navigation/native'
  import { createBottomTabNavigator } from '@react-navigation/bottom-tabs'
  import { Adrop } from 'adrop-ads-react-native'
  import BannerExample from './views/BannerExample'
  import NativeAdExample from './views/NativeAdExample'
  import InterstitialAdExample from './views/InterstitialAdExample'
  import RewardedAdExample from './views/RewardedAdExample'
  import PopupAdExample from './views/PopupAdExample'

  const Tab = createBottomTabNavigator()

  const App = () => {
      useEffect(() => {
          // Initialize Adrop SDK
          Adrop.initialize(false) // test mode: false, production: true
      }, [])

      return (
          <NavigationContainer>
              <Tab.Navigator>
                  <Tab.Screen
                      name="Banner"
                      component={BannerExample}
                  />
                  <Tab.Screen
                      name="Native"
                      component={NativeAdExample}
                  />
                  <Tab.Screen
                      name="Interstitial"
                      component={InterstitialAdExample}
                  />
                  <Tab.Screen
                      name="Rewarded"
                      component={RewardedAdExample}
                  />
                  <Tab.Screen
                      name="Popup"
                      component={PopupAdExample}
                  />
              </Tab.Navigator>
          </NavigationContainer>
      )
  }

  export default App
  ```
</CodeGroup>

***

## Best Practices

### 1. Memory Management

Always clean up ad objects after use.

```typescript theme={null}
useEffect(() => {
    const nativeAd = new AdropNativeAd('YOUR_UNIT_ID')

    return () => {
        nativeAd.destroy()
    }
}, [])
```

### 2. Error Handling

Implement error handling for all ad loads.

```typescript theme={null}
const [error, setError] = useState<string | null>(null)

const handleAdFailedToReceive = (unitId: string, errorCode?: string) => {
    setError(errorCode ?? 'Unknown error')
    // Error logging, display fallback content, etc.
}
```

### 3. State Management

Track ad state using Hooks.

```typescript theme={null}
const { isLoaded, isOpened, isReady, errorCode } = useAdropInterstitialAd(unitId)

// Disable button
<Button
    disabled={!isLoaded}
    title="Show Ad"
    onPress={show}
/>
```

### 4. Platform Branching

Use different unit IDs for each platform.

```typescript theme={null}
const unitId = useMemo(() => {
    return Platform.OS === 'android'
        ? 'ANDROID_UNIT_ID'
        : 'IOS_UNIT_ID'
}, [])
```

### 5. Use Test Unit IDs

Always use test unit IDs during development and testing.

```typescript theme={null}
const isProduction = false

const unitId = isProduction
    ? 'YOUR_PRODUCTION_UNIT_ID'
    : 'PUBLIC_TEST_UNIT_ID_320_50'
```

***

## Next Steps

<CardGroup cols={2}>
  <Card title="API Reference" href="/sdk/react-native/reference">
    Check the complete API documentation
  </Card>

  <Card title="Banner Ads" href="/sdk/react-native/banner">
    Detailed banner ad guide
  </Card>

  <Card title="Native Ads" href="/sdk/react-native/native">
    Detailed native ad guide
  </Card>

  <Card title="Interstitial Ads" href="/sdk/react-native/interstitial">
    Detailed interstitial ad guide
  </Card>
</CardGroup>
