JavaScriptNext.jsReact

Next.jsでGoogle Adsenseを使った広告配信

妙にハマりまくったので、とりあえず現状について覚書 参考 https://yuyauver98.me/no-slot-size-for-availablewidth0/ https://mao-tss.medium.co […]

広告ここから
広告ここまで

妙にハマりまくったので、とりあえず現状について覚書

参考

pages/_document.tsx

Google Adsenseのscriptタグをここで読ませます。react-helmetを使えばまとめられる気もしますが、ライブラリ化するわけでもないので今はこれでよしとしています。

      <Html>
        <Head>
          <script
            async
            src="https://wp-kyoto.net//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"
            data-ad-client="ca-pub-xxxxxxx"
          ></script>
        </Head>

@types/window.d.tsで型を拡張

windowadsbygoogleが追加されるので、型を定義しておきます。

/* eslint-disable no-var */
interface Window {
    prerenderReady: boolean;
    adsbygoogle: {[key: string]: unknown}[]
}
  
declare global {
    var window: Window;
}

コンポーネントを作成

react-adsenseのコードなどを参考にコンポーネントを作ります。

import React, {CSSProperties, FC, useEffect} from 'react'

export type GoogleAdsenseProps = {
  className?: string;
  style?: CSSProperties;
  client: string;
  slot: string;
  layout?: string;
  layoutKey?: string;
  format?: string;
  responsive?: string;
};

export const GoogleAdsense: FC<GoogleAdsenseProps> = ({
  className = '',
  style = {display: 'block'},
  format = 'auto',
  layout = '',
  layoutKey = '',
  responsive = 'false',
  client,
  slot,
}) => (
    <ins className={`${className} adsbygoogle`}
      style={style}
      data-ad-client={client}
      data-ad-slot={slot}
      data-ad-layout={layout}
      data-ad-layout-key={layoutKey}
      data-ad-format={format}
      data-full-width-responsive={responsive}></ins>
);

pages/_app.tsxでイベント発火

あとはwindow.addsbygoogleを実行するフックを追加します。

const useGoogleAdsense = () => {
  const loadAd = useCallback(() => {
    (window.adsbygoogle = window.adsbygoogle || []).push({})
  },[])

  useEffect(() => {
    if(typeof window !== 'undefined'){
      const component = window.document.getElementById('__next').querySelector(`.adsbygoogle`);
      if (component) {
        component.addEventListener('load', loadAd);
      }
    }
    return () => {
      if(typeof window !== 'undefined'){
        const component = window.document.getElementById('__next').querySelector(`.adsbygoogle`);
        if (component) {
          component.removeEventListener('load', loadAd);
        }
      }
    }
  }, [])
}

function MyApp({ Component, pageProps }) {
  useGoogleAdsense()
  return (
            <Component {...pageProps} />
  )
}

Next.jsアプリ配下に広告タグがあれば実行。なければ何もしないというフックにしています。

window.onloadで読み込みしているサンプルが多かったのですが、Next.jsやGatsbyでは使わない方が良さそうです。というのもこの辺りのFWを使った場合、ページ遷移時にwindow.onloadイベントが発火しない様子で、広告が表示されませんでした。

そのため今回のサンプルではちょっと手間ですが、querySelectorで要素を取得し、addEventListnerでloadイベントをセットする形を採用しています。

ページ毎にuseEffectを白化させる

もしページ遷移のたびにHookを動かしたい場合はこうします。

import { useRouter } from 'next/router';
...
  const {asPath} = useRouter()
  useEffect(() => { ... }, [asPath])

ある程度整理できたら、ライブラリ化できないか検討しようかなとは思っています。

ブックマークや限定記事(予定)など

WP Kyotoサポーター募集中

WordPressやフロントエンドアプリのホスティング、Algolia・AWSなどのサービス利用料を支援する「WP Kyotoサポーター」を募集しています。
月額または年額の有料プランを契約すると、ブックマーク機能などのサポーター限定機能がご利用いただけます。

14日間のトライアルも用意しておりますので、「このサイトよく見るな」という方はぜひご検討ください。

広告ここから
広告ここまで

Related Category posts