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月だしどうなんだろう。