Gatsby製のブログで画面遷移時にadsbygoogle.push() error
発生した問題
本ブログにおいて、記事内遷移があった場合に以下のエラーが発生して画面が真っ白になる問題がいつの間にか起こっていた。
adsbygoogle.push() error: All ins elements in the DOM with class=adsbygoogle already have ads in them.
メッセージを読むに、adsbygoogle.push()を実行した際にadsbygoogleという要素クラスを持つins要素が既に広告を持っていることによるエラーのようだ。この時点ではまだよく分かっていない。
原因
エラーメッセージにあるadsbygoogle.push()を呼び出している箇所を探してみると、以下のようになっていた。
useEffect(() => {
const adsbygoogle = window.adsbygoogle || []
adsbygoogle.push({})
})
バグのあるところにuseEffectあり(自分が悪い)。久しぶりなのでドキュメントを読んでみる。
useEffectの第二引数に、
- 何も指定しないとレンダーごとに関数を実行
- 値入りの配列を指定すると、マウント時とその値に変更があった場合に関数を実行
- 空配列を指定すると、マウント時とアンマウント時に関数を実行 するようだ。
エラーの内容に戻るが、今回のエラーの原因はuseEffectの第二引数に何も指定していなかったのでadsbygoogle.push()がレンダーごとに呼ばれてしまい、広告の表示が重複されてしまったためだろう。
解決法
不必要なadsbygoogle.push()が実行されてしまっていることが原因なので、1ページに1回だけこれが実行されるようにしたい。
そこで、useEffectの第二引数に現在のURLのパスを与えることにした。
useEffect(() => {
const adsbygoogle = window.adsbygoogle || []
adsbygoogle.push({})
}, [path])
これでエラーが起こることもなくなった。ちなみにpathはlocation.pathnameから取得してコンポーネントのpropsに渡すことで取得している。
補足
ちなみに今回の対応をするにあたって広告プラグインについても調査してみた。
今まではgatsby-plugin-google-adsenseというプラグインを使用したが、npmのページでこれを確認してみると既にDeprecatedになっていた。
代替のプラグインとしては以下を見つけたが、GitHubのスター数も少ないし直近の更新が2021年4月だしどうなんだろう。