[Next.js] Google Adsenseを表示させる方法

環境

  • next: 10.1.2
  • typescript: 4.2.3

条件

ブログの記事に Adsense を表示したい。記事は次の記事、前の記事に遷移できるリンクがあるため、記事の読み込み毎に広告を再読み込みさせる。

方法

adsbygoogle.js を読み込む

pages/_document.tsx でスクリプトを読み込む。

// pages/_document.tsx
render() {
  return (
    <Html>
      <Head>
        <script
          data-ad-client={GOOGLE_ADSENSE.CLIENT}
          async
          src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"
        ></script>
      </Head>
    </Html>
  )
}

adsbygoogle の型定義

windowの adsbygoogle へアクセスをする必要が出てくるので型定義する。

// next-env.d.ts
interface Window {
  adsbygoogle?: { [key: string]: unknown }[];
}

ひとまず、next-env.d.ts に定義した。

Adsense コンポーネントを作成する

// components/Adsense.tsx
import { useRouter } from "next/router";
import React, { useEffect } from "react";

const Adsense = () => {
  const { asPath } = useRouter();

  useEffect(() => {
    try {
      (window.adsbygoogle = window.adsbygoogle || []).push({});
    } catch (err) {
      console.log(err);
    }
  }, [asPath]);

  return (
    <div key={asPath}>
      <ins
        className="adsbygoogle"
        style={{ display: "block", textAlign: "center" }}
        data-ad-layout="xxx"
        data-ad-format="xxx"
        data-ad-client="xxx"
        data-ad-slot="xxx"
      />
    </div>
  );
};

adsbygoogle の再セット

asPathuseEffect に渡して、ページ遷移毎に window.adsbygoogle.push({}) するようにする。

これを指定しておかないと遷移しても広告が再読み込みされない。

DOM の更新通知

<div key={asPath}></div>

親要素にkeyを指定しておくことで、どの要素に変更があったかを通知する。今回は、ページ遷移毎に更新したいので、useRouter().asPathを渡しておく。

これを更新しておかないと既にイベントを適用している旨のエラーがでてしまう。

"adsbygoogle.push() error: All ins elements in the DOM with class=adsbygoogle already have ads in them."