Next.js に Google Adsense を設置する

imatomix
2021年11月19日 7:50

概要

今回、記事下部に Google Adsense を設置しました。その際に行った手順の記録です。

しばらく見てなかったですが、 ここのところ Google Analytics や Adsense、 firebase、 Amazon AWS でさえも、UIデザインが細かくアップデートされてるようで、触っててとても楽しいです。

Adsenseからのコード

Adsense から以下のようなコードを渡されるので、Next.jsの適所に配置していく。
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=xxx" crossorigin="anonymous"></script> <ins class="adsbygoogle" style="display:block" data-ad-client="xxx" data-ad-slot="xxx" data-ad-format="auto" data-full-width-responsive="true"></ins> <script> (adsbygoogle = window.adsbygoogle || []).push({}); </script>

head で adsbygoogle.js を読み込む

/pages/_document.tsxにて、<Head></Head>内にadsbygoogle.js の読み込みスクリプトを配置する。
/pages/_document.tsx
<Head> <script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=xxx" crossOrigin="anonymous"></script> </Head>

window に型を定義する

上のスクリプトによりwindowadbygoogle が追加される。この後の広告表示用のコンポーネントからadbygoogle にアクセスする必要があるので、Typescript の場合は型を定義しておく。

window への型定義は /@types/window.d.ts ファイルにて行う。
/@types/window.d.ts
interface Window { adsbygoogle?: { [key: string]: unknown }[] } declare global { const window: Window }

Adsense コンポーネントの作成

最後のスクリプトはページ表示時に実行する必要があるため、useEffect を使用する。ページ遷移に対応するためにuseEffect には router.asPath を渡しておく。

data-adtestonにするとテストモードになり、クリックとインプレッションが記録されなくなるらしいので、production環境以外ではテストモードになるようにしておく
/src/components/adsense.tsx
import { useRouter } from 'next/router' import { useEffect } from 'react' const Adsense: React.FC = () => { const { asPath } = useRouter() useEffect(() => { try { ;(window.adsbygoogle = window.adsbygoogle || []).push({}) } catch (err) { console.log(err) } }, [asPath]) return ( <ins className='adsbygoogle' style={ display: 'block' } data-adtest={process.env.NODE_ENV === 'production' ? 'off' : 'on'} data-ad-format='auto' data-ad-client='xxx' data-ad-slot='xxx' data-full-width-responsive='true' /> ) } export default Adsense
後はこのコンポーネントを広告を表示したい場所に設置すし、必要に応じてスタイルを調整する。

困ったこと

Adsenseを設置すると、広範囲の親要素にわたって強制的に以下のスタイルが適用される。
height: auto !important; min-height: 0px !important;
このスタイルは(Next.js とかだと)ページ遷移後も残ってしまうので、場合によってこれがレイアウトを崩してしまうかもしれない。実際に、本サイトではノートページを経由後にフッターの位置がずれるページが発生した。<main>タグに適用された上記スタイルが原因だった。
対応策として、以下のようにAdsenseコンポーネントが破棄される際に上記スタイルを除去する処理を追加した。
useEffect(() => { try { ;(window.adsbygoogle = window.adsbygoogle || []).push({}) } catch (err) { console.log(err) } // 以下を追加 return () => { document.querySelector('main').removeAttribute('style') } }, [asPath])