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

# WebView 가이드

> React Native WebView에서 백필 광고를 표시하는 방법

## 개요

React Native 앱의 WebView에서 백필 광고를 표시할 수 있습니다. Adrop SDK는 간편한 통합을 위한 `useAdropWebView` 훅과 수동 `registerWebView` API를 제공합니다.

***

## 사전 요구사항

프로젝트에 `react-native-webview` 패키지를 설치하세요.

<CodeGroup>
  ```bash npm theme={null}
  npm install react-native-webview
  ```

  ```bash yarn theme={null}
  yarn add react-native-webview
  ```
</CodeGroup>

<Warning>
  WebView 백필 광고는 Android와 iOS 모두에서 `adrop-ads-backfill` 설정이 필요합니다. 설정 방법은 [시작하기](/ko/sdk/react-native/overview)를 참고하세요.
</Warning>

***

## 플랫폼 설정

WebView에서 백필 광고를 활성화하려면 네이티브 플랫폼 설정이 필요합니다.

<Tabs>
  <Tab title="Android">
    `android/app/src/main/AndroidManifest.xml`에 다음을 추가하세요:

    ```xml AndroidManifest.xml theme={null}
    <manifest>
        <application>
            <!-- WebView 백필 광고 통합 -->
            <meta-data
                android:name="com.google.android.gms.ads.INTEGRATION_MANAGER"
                android:value="webview"/>
        </application>
    </manifest>
    ```
  </Tab>

  <Tab title="iOS">
    `ios/{YourApp}/Info.plist`에 다음 키를 추가하세요:

    ```xml Info.plist theme={null}
    <key>GADIntegrationManager</key>
    <string>webview</string>
    ```
  </Tab>
</Tabs>

<Warning>
  이 설정은 WebView에서 백필 광고가 정상적으로 작동하는 데 필요합니다. 설정이 없으면 백필 광고가 표시되지 않을 수 있습니다.
</Warning>

***

## useAdropWebView 훅 사용 (권장)

`useAdropWebView` 훅이 WebView 등록을 자동으로 처리합니다.

```tsx theme={null}
import React from 'react'
import { View } from 'react-native'
import { WebView } from 'react-native-webview'
import { useAdropWebView } from 'adrop-ads-react-native'

const WebViewScreen: React.FC = () => {
    const { containerRef, isReady, onLayout } = useAdropWebView()

    return (
        <View ref={containerRef} style={{ flex: 1 }} onLayout={onLayout}>
            <WebView
                source={isReady ? { uri: 'https://your-website.com' } : { html: '' }}
                style={{ flex: 1 }}
                javaScriptEnabled={true}
                thirdPartyCookiesEnabled={true}
                mediaPlaybackRequiresUserAction={false}
                allowsInlineMediaPlayback={true}
            />
        </View>
    )
}
```

**반환값:**

| 프로퍼티           | 타입                      | 설명                           |
| -------------- | ----------------------- | ---------------------------- |
| `containerRef` | `React.RefObject<View>` | WebView를 감싸는 `View`에 연결할 ref |
| `isReady`      | `boolean`               | WebView 등록 완료 여부             |
| `onLayout`     | `() => void`            | 레이아웃 시 등록을 트리거하는 콜백          |

<Note>
  `isReady`가 `true`가 된 후에 웹 콘텐츠를 로드하세요. 등록 완료 전에 URL을 전달하면 광고가 표시되지 않을 수 있습니다.
</Note>

***

## 수동 등록

`Adrop.registerWebView`를 사용하여 수동으로 WebView를 등록할 수도 있습니다.

```tsx theme={null}
import React, { useEffect, useRef, useState } from 'react'
import { findNodeHandle, View } from 'react-native'
import { WebView } from 'react-native-webview'
import { Adrop } from 'adrop-ads-react-native'

const WebViewScreen: React.FC = () => {
    const containerRef = useRef<View>(null)
    const [isReady, setIsReady] = useState(false)

    useEffect(() => {
        const register = async () => {
            if (containerRef.current) {
                const tag = findNodeHandle(containerRef.current)
                if (tag != null) {
                    await Adrop.registerWebView(tag)
                    setIsReady(true)
                }
            }
        }
        register()
    }, [])

    return (
        <View ref={containerRef} style={{ flex: 1 }}>
            <WebView
                source={isReady ? { uri: 'https://your-website.com' } : { html: '' }}
                style={{ flex: 1 }}
                javaScriptEnabled={true}
                thirdPartyCookiesEnabled={true}
                mediaPlaybackRequiresUserAction={false}
                allowsInlineMediaPlayback={true}
            />
        </View>
    )
}
```

<Warning>
  `react-native-webview`의 ref는 imperative handle이므로 `findNodeHandle`이 직접 동작하지 않습니다. WebView를 `View`로 감싸고 해당 `View`의 ref를 사용하세요.
</Warning>

***

## WebView 설정

백필 광고가 정상적으로 동작하려면 다음 WebView props가 필요합니다:

| Prop                              | 값       | 설명                    |
| --------------------------------- | ------- | --------------------- |
| `javaScriptEnabled`               | `true`  | JavaScript 실행 활성화     |
| `thirdPartyCookiesEnabled`        | `true`  | 서드파티 쿠키 활성화 (Android) |
| `mediaPlaybackRequiresUserAction` | `false` | 미디어 자동 재생 허용          |
| `allowsInlineMediaPlayback`       | `true`  | 인라인 미디어 재생 허용 (iOS)   |

***

## 외부 URL 처리

앱에서 자사 도메인이 아닌 URL을 외부 브라우저로 여는 로직이 있는 경우, 광고 리소스 요청(예: `googleads.g.doubleclick.net`)이 차단되지 않도록 해야 합니다.

광고 리소스(iframe, 스크립트 등)는 광고 SDK가 자동으로 로드하며, 사용자가 직접 클릭한 것이 아닙니다. **사용자가 직접 클릭한 이동**에 한해서만 외부 브라우저로 전환하세요.

```tsx theme={null}
import { Linking } from 'react-native'

const allowedHost = 'my-domain.com'

<WebView
    source={{ uri: 'https://my-domain.com' }}
    style={{ flex: 1 }}
    javaScriptEnabled={true}
    thirdPartyCookiesEnabled={true}
    mediaPlaybackRequiresUserAction={false}
    allowsInlineMediaPlayback={true}
    onShouldStartLoadWithRequest={(request) => {
        const url = request.url
        const host = new URL(url).host

        // 사용자가 직접 클릭한 경우에만 외부 브라우저로 이동
        // 광고 리소스(예: googleads.g.doubleclick.net)는 iframe/스크립트로 로드되므로 차단하지 않음
        if (!host.includes(allowedHost) && request.navigationType === 'click') {
            Linking.openURL(url)
            return false
        }

        return true
    }}
/>
```

<Warning>
  자사 도메인이 아닌 모든 요청을 차단하거나 리다이렉트하지 마세요. `googleads.g.doubleclick.net` 같은 광고 리소스는 백필 광고 과정에서 자동으로 로드되며, WebView 내에서 정상적으로 로드되어야 합니다.
</Warning>

***

## 관련 문서

<CardGroup cols={2}>
  <Card title="배너 광고" icon="rectangle-ad" href="/ko/sdk/react-native/banner">
    배너 광고 연동 방법
  </Card>

  <Card title="레퍼런스" icon="book" href="/ko/sdk/react-native/reference">
    API 레퍼런스
  </Card>

  <Card title="예제" icon="code" href="/ko/sdk/react-native/examples">
    예제 코드
  </Card>
</CardGroup>
