Google AdsenseをReactで使う方法(パッケージ未使用)

# 概要

ReactのようなSPAの場合、Google Adsense（以降、Adsense）は従来の要求ごとにHTMLを返すSSRが前提となっているため、導入には工夫が必要になります。
公式ドキュメントにSPAに対応する記事がないので、どうやって導入するか記事にしました。
広告の種類はレスポンシブ対応で、推奨されているディスプレイ広告を使用します。（設定いらず）

本記事ではReact向けのパッケージは利用しません。

# 読者対象

- ReactアプリでAdsenseを導入したいが、パッケージを導入したくない。


# Road to Adsense

## どうしてパッケージを導入しないのか？

パッケージを導入するかの判断基準として、独自での開発工数とバンドルサイズ増加をはかりにかけたとき、導入したほうがメリットが大きいかどうかで見ています。
今回の場合、そもそもAdsenseの広告が単純化したことでパッケージで処理されるべき処理がないと判断。
またパッケージ導入時のデメリットとして、更新頻度が低いとトレンドから取り残されるのが嫌なので、対応できるものは自分で対応したい。
（クラスコンポーネントやhook未使用等）

Adsenseの広告が単純化の概要。
https://support.google.com/adsense/answer/9193354

## まずはAdsenseのページを読む（SSR向け）

公式ドキュメント
https://support.google.com/adsense/answer/9183566
要するに、広告を管理画面で作り、そのコードを張り付ければいいだけ。

どのようなコードなのか？公式ドキュメントのサンプルを引用。
https://support.google.com/adsense/answer/9190028?hl=ja

>```javascript
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<!-- Homepage Leaderboard -->
<ins class="adsbygoogle"
style="display:inline-block;width:728px;height:90px"
data-ad-client="ca-pub-1234567890123456"
data-ad-slot="1234567890"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
```

スクリプト読み込んで、insタグ一つ設置して、あとはpush()を実行するだけと単純明快。

## 実際にアプリに導入する

ではまずAdsense導入のために、index.htmlにスクリプト読み込みの行を追加します。
（adsbygoogle.jsは一度読み込めばいいのでindex.htmlで読み込んでおく）

```html:index.html
    <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
    <!-- 自動広告併用なら以降が必要 -->
    <script>
      (adsbygoogle = window.adsbygoogle || []).push({google_ad_client: '%REACT_APP_GOOGLE_AD_CLIENT%',enable_page_level_ads: true});
    </script>
```

スクリプト読み込みの行はいいとして、スクリプトの中身が少し異なっています。
これは自動広告を併用しているためで、自動広告を使用しない場合は不要です。
SPAの場合、自動広告が効果を出せるのは初回アクセスページのみのため、使う方は少数だと思われます。
ただし自動広告はオーバーレイ広告というものがあり、自動広告でしか出せないので私は併用しています。
自動広告に興味がある方はググってみてください。

話を戻すと、adsbygoogle.jsを読み込むことでwindow.adsbygoogleに```push()```メソッドを所有するオブジェクトが設定されます。
adsbygoogleを利用する準備が整いました。

## Adsense用コンポーネントを作成

次に広告を表示するコンポーネント(ここではAdsCardと命名)を作成します。

```javascript

import React, { useEffect } from 'react';

export default function AdsCard(props) {
    useEffect(() => {
        if (window.adsbygoogle && process.env.NODE_ENV !== "development") {
            window.adsbygoogle.push({});
        }
    }, [])

    return (
        <ins className="adsbygoogle"
            style={{ "display": "block" }}
            data-ad-client={process.env.REACT_APP_GOOGLE_AD_CLIENT}
            data-ad-slot={process.env.REACT_APP_GOOGLE_AD_SLOT}
            data-ad-format="auto"
            data-full-width-responsive="true"></ins>
    );
}
```

まずはreturn内を見ていきます。その前に、私が広告を作成して受け取った```<ins>```は以下の通り。（data-ad-clientとdata-ad-slotは個人と結びついた値）

```javascript
<ins class="adsbygoogle"
     style="display:block"
     data-ad-client="<<your-ad-client>>"
     data-ad-slot="<<your-ad-slot>>"
     data-ad-format="auto"
     data-full-width-responsive="true"></ins>
```

まずは```class```を```className```に機械的に変更。（Reactの基本）
次に```style```の値を```{{...}}```に機械的に変更。（Reactの基本）
最後にそのままでもいいのですが、process.env.REACT_APP_GOOGLE_AD_＊という環境変数を作って格納しています。
環境変数について知りたい場合はCreateReactAppのドキュメントを参考にしてください。
https://facebook.github.io/create-react-app/docs/adding-custom-environment-variables

残るは関数冒頭の```useEffect()```です。
広告を配信するには```adsbygoogle.push({})```のコールが必要になるので、```useEffect()```を使って1回コールするようにします。
開発環境では広告は許可されていないため403応答が来ます。
それを防止するため、条件に```process.env.NODE_ENV !== "development"```を追加しています。

これでコンポーネントが完成したので、あとは広告を表示したいところに張り付ければ本番環境で広告が表示されるようになります。


#おまけ

広告の配置にはいくつか注意点があります。ポリシー違反にならないよう読んでおきましょう。
公式ドキュメント 見出し「広告の配置」
https://support.google.com/adsense/answer/48182
https://support.google.com/adsense/answer/1346295#Ad_limit_per_page
広告配置のベストプラクティス
https://support.google.com/adsense/answer/1282097?hl=ja