Next.js App Routerで作ったサイトにGoogleアドセンスを導入する
2023/10/132023/12/28

Next.js App Routerで作ったサイトにGoogleアドセンスを導入する

3 mins to read

Next.jsを使う場合、アドセンスコードをそのまま使う事ができません。ちょっと工夫が必要だったので記録しておきます。

前提

使用するNext.jsのバージョンは13.5.4でApp Routerを使っています。

また、Google Adsense側の設定は終わっていて、以下のような広告コードが手元にあるということを前提としています。

<script
  async
  src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=パブリッシャーID"
  crossorigin="anonymous"></script>
<ins
  class="adsbygoogle"
  style="display:block"
  data-ad-client="パブリッシャーID"
  data-ad-slot="広告スロットID"
  data-ad-format="auto"
  data-full-width-responsive="true"></ins>
<script>
  (adsbygoogle = window.adsbygoogle || []).push({});
</script>

このコードのパブリッシャーID広告スロットIDの部分をひかえておいてください。

layout.tsxでscriptを読み込み

上記のコードの<script>の部分はページごとに一回読み込めば大丈夫なので、広告コンポーネントとは別でスクリプトコンポーネントを作って、layout.tsx内で一回だけ読み込ませます。

googleads-script.tsx
import Script from "next/script";

const PUBLISHER_ID = "xxxxxxxxxxxxxxxxx";

export const GoogleAdScript = () => {
  if (process.env.VERCEL_ENV === "production") {
    return (
      <Script
        async
        src={`https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-${PUBLISHER_ID}`}
        crossOrigin="anonymous"
        strategy="afterInteractive"
      />
    );
  }
  return <></>;
};

パブリッシャーIDはご自分のものに書き換えてください。

ポイントはnext/scriptを使うところと、strategy="afterInteractive"を指定する部分です。

beforeInteractiveを指定した場合、最初に読み込むJSのサイズが大きくなるため、PageSpeedInsightのスコアがめちゃくちゃ下がるので注意してください。

lazyOnLoadでも問題なさそうだったんですが、ちょくちょくエラーが出るのでafterInteractiveを採用しました。

こちらのコンポーネントをapp/layout.tsxで以下のようにして呼び出します。

app/layout.tsx
import { Footer } from "@/components/layout/footer";
import { Header } from "@/components/layout/header";
import { GoogleAdScript } from "@/components/googleads-script";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <div className="min-h-screen">
      <Header />
      <main>
        {children}
      </main>
      <Footer />
      <GoogleAdScript />
    </div>
  );
}

広告コンポーネント

広告コンポーネントは以下のような感じになります。

components/googlead.tsx
"use client";

import { useEffect } from "react";
import { usePathname } from "next/navigation";

const PUBLISHER_ID = "xxxxxxxxxxxxxxxxx";

declare global {
  interface Window {
    adsbygoogle: { [key: string]: unknown }[];
  }
}

type GoogleAdProps = {
  slot: string;
  format?: string;
  responsive?: string;
  style?: any;
};

const GoogleAd = ({
  slot,
  format = "auto",
  responsive = "true",
  style,
}: GoogleAdProps) => {
  let pathname = usePathname();
  pathname = pathname ? pathname : "";

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

  return (
    <div key={pathname.replace(/\//g, "-") + "-" + slot}>
      <ins
        className="adsbygoogle"
        style={{ display: "block", width: "100%", ...style }}
        data-ad-client={`ca-pub-${PUBLISHER_ID}`}
        data-ad-slot={slot}
        data-ad-format={format}
        data-full-width-responsive={responsive}
      />
    </div>
  );
};

export default GoogleAd;

パブリッシャーIDはご自分のものに書き換えてください。

使い方

slotだけが必須のpropになります。
最初にひかえておいた広告スロットIDをここに入力してください

<GoogleAd slot="xxxxxxxxxx" />

styleを指定したい場合はこういう感じでCSSを渡してください。

<GoogleAd slot="xxxxxxxxxx" style={{ width: '100%', height: '60px' }} responsive="false" />

こちらのやり方で問題なく広告が表示される事と利益が発生する事を確認できましたので、アドセンスを利用したい方は是非お試しください🥳

追記: 自動広告について

以上の方法で手動広告は問題なく導入できるんですが、自動広告を導入したい場合は、ページ内のリンク移動に<Link>を使うのをやめて、<a>を使ってください。

<Link>の恩恵を受けれなくなってしまいますが、今の所はこれ以外の方法でアドセンスの自動広告に対応する方法はなさそうです😢