[AdSense] Astro(静的サイト)に自動広告と手動ユニットを入れる

Tech
[AdSense] Astro(静的サイト)に自動広告と手動ユニットを入れる

WordPress 時代に入れていた Google AdSense を、Astro への移行に合わせて再設置しました。 自動広告(Auto Ads)と手動ユニットの併用で入れたのと、Astro 特有のハマりどころがあったのでまとめます。

ローダーは <head> に1回だけ

AdSense のローダースクリプトを全ページの <head> に置きます。これを読み込むこと自体が自動広告も有効化します(ON/OFF は AdSense 管理画面側で制御)。

---
// src/components/AdSenseLoader.astro
const client = 'ca-pub-XXXXXXXXXXXXXXXX';
---
<script
  async
  is:inline
  src={`https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=${client}`}
  crossorigin="anonymous"
></script>

is:inline を付けて、Astro にバンドルさせずそのまま出力させるのがポイントです。これを BaseLayout<head> に置きます。

ads.txt を忘れずに

AdSense はサイト所有者の認証に ads.txt を見ます。public/ads.txt に置けば、ビルド時に dist/ 直下へコピーされます。

google.com, pub-XXXXXXXXXXXXXXXX, DIRECT, f08c47fec0942fa0

pub- 以降はパブリッシャー ID(ca-pub- を除いた数字部分)です。

手動ユニットをコンポーネント化する

記事下・サイドバーなど、位置を自分で決めたいところは手動ユニットを使います。<ins> と push をコンポーネントにまとめておくと使い回しが楽です。

---
// src/components/AdUnit.astro
const client = 'ca-pub-XXXXXXXXXXXXXXXX';
const { slot } = Astro.props;
---
<ins
  class="adsbygoogle"
  style="display:block"
  data-ad-client={client}
  data-ad-slot={slot}
  data-ad-format="auto"
  data-full-width-responsive="true"
></ins>
<script is:inline>(adsbygoogle = window.adsbygoogle || []).push({});</script>

あとは置きたい場所で <AdUnit slot="..." /> と書くだけです。

ハマりどころ:.map() の中だと広告が描画されない

記事一覧の「3記事目の後」にインフィード広告を挟もうとして、.map() の中に <Fragment> でコンポーネントを差し込んだら、そのコンポーネントだけ出力されない現象に遭遇しました。<div> など素の要素や PostCard は出るのに、AdUnit だけ消えるという挙動です。

<!-- これだと AdUnit が描画されないことがあった -->
{posts.map((post, i) => (
  <Fragment>
    <PostCard {...post.data} />
    {i === 2 && <AdUnit slot="..." />}
  </Fragment>
))}

.map() の外に出すと正常に描画されたので、配列を分割してループの外に広告を置く形に変更して解決しました。

<!-- 配列を分割して、広告はループの外に置く -->
{posts.slice(0, 3).map((post) => <PostCard {...post.data} />)}
{posts.length > 3 && <AdUnit slot="..." />}
{posts.slice(3).map((post) => <PostCard {...post.data} />)}

開発中に枠位置を確認したいとき

ローカル(astro dev)では実際の広告は表示されません。位置の確認だけしたいときは、import.meta.env.DEV で開発時だけプレースホルダーの枠を出すようにしておくと便利でした。

---
const isDev = import.meta.env.DEV;
---
{isDev ? (
  <div style="min-height:120px;border:2px dashed #9aa7d4;">広告枠(プレビュー)</div>
) : (
  <ins class="adsbygoogle" /* ...本番の広告... */></ins>
)}

メモ

  • 自動広告と手動ユニットを併用すると広告が重なりがち。管理画面側で自動広告を控えめ(サイドレール程度)に絞ると整う。
  • AdSense はパーソナライズ広告で Cookie を使うので、プライバシーポリシーに Cookie 利用とオプトアウト導線を書いておくこと(プログラムポリシー要件)。
  • 新規サイトはローダー設置後に審査が通って初めて広告が出る。

静的サイトでも、ローダーと ads.txt、手動ユニットのコンポーネント化さえ押さえれば、WordPress 時代と同じ感覚で運用できました。

AdSense, Astro