> ## 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`の設定が必要です。設定方法は[はじめに](/ja/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`になってからWebコンテンツをロードしてください。登録完了前に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`  | サードパーティCookieを有効化（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="/ja/sdk/react-native/banner">
    バナー広告の実装方法
  </Card>

  <Card title="リファレンス" icon="book" href="/ja/sdk/react-native/reference">
    APIリファレンス
  </Card>

  <Card title="サンプル" icon="code" href="/ja/sdk/react-native/examples">
    サンプルコード
  </Card>
</CardGroup>
