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="//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])

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

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark