スマホ 1 台を回して 3〜8 人で遊ぶパーティーゲームのサイト「まわして」(mawashite.com) を 1 人で作っています。執筆時点 (2026-08-02) で 10 本のゲームを公開している、Astro の静的サイト + Preact island 構成のサービスです。
このサイトに AdSense を入れるとき、コードを確定させる前に、アドオプス・マーケティング・UX/アクセシビリティ・SEO/Core Web Vitals・教育現場の 5 つの専門家ペルソナを AI に演じさせ、配置案を現物ごとレビューさせました。
このサイトの AdSense はまだ審査中で、広告収益は 0 円です。この記事は収益が出たあとの武勇伝ではなく、その手前の配置設計の記録で、出てくる実測値はすべて配信前の計測 (プレースホルダーと枠要素の実寸、レビュー時の CLS 計測) です。
広告を貼ること自体はコピペで終わりますが、難しいのは「どこに置かないか」の判断で、これはアドオプスの経験がないと材料すら持てません。5 つのペルソナに配置案を見せてわかったのは、AI に専門家ペルソナを演じさせたレビューは、新しい配置を承認する用途より、既存の配置を消す判断に強く効くということです。
広告配置の判断に AI レビューを組み込みたい個人開発者を対象読者にしています。
5 人の専門家ペルソナに、配置案をレビューさせた
広告ユニットは位置別に 6 つ用意しました。1 ユニットの使い回しでは「どの枠が稼いでいるか」が永久に分からなくなる、というアドオプスの指摘を踏まえ、ユニット = 位置、URL チャネル (管理画面でページ群ごとの成績を見る機能) = ページ種別、の二軸にしています。ゲーム画面 /play/ はセットアップと最終結果の 2 画面だけ、記事は本文内 1〜2 枠。枠の実体は素の AdSense です。
<ins
class="adsbygoogle w-full"
style="display:block"
data-ad-client={ADSENSE_CLIENT}
data-ad-slot={slot}
data-ad-format="auto"
data-full-width-responsive="true"
/>
<script is:inline>
(window.adsbygoogle = window.adsbygoogle || []).push({});
</script>
スロット ID は環境変数でなくコード定数です (広告の設定を 1 か所にまとめたファイル ads.ts に 6 つ並べただけ)。配信 HTML にそのまま載る公開情報なので、秘匿する理由がありません。
レビューは、AI のサブエージェント (1 つの役割を独立して担当させる、AI の実行単位。詳しくは前の記事に書きました) に役割定義と現物——配置済みのコード、実寸プレースホルダーを表示した開発環境のプレビュー——を渡し、blocker / major / minor の 3 段階で指摘を報告させるやり方です。
1 ペルソナ 1 セッションで、互いの出力は見せません。すべての指摘を採用したわけではなく、コストに見合わないと判断して却下した提案もあります。
レビューで消えた枠、生まれたルール
いちばん大きい戻しは、記事ページと一覧ページのタイトル直下に置いていた枠の全撤去でした (ゲーム紹介ページのヒーロー下の枠だけは、後述の撤去基準つきで残しています)。理由は 3 つです——検索から着地した瞬間の第一印象を広告が取る、読み込みでレイアウトが動いた瞬間の誤クリックを誘う、薄いページが広告過多になる。「ページ上部ほど見られる」という素人の直感は、そのまま「ページ上部ほど壊すものが多い」でした。
寸法の事故も 2 件見つかりました。シーン一覧ページ (学校の学級レクや飲み会など、利用シーン別にゲームを紹介するページ) の末尾に置いた Multiplex (レコメンド風の大型枠) は実寸 1,635px あり、短いページではページの高さの 62% が広告になっていました。
記事の 1 枠目も、リード文の直後に置いた案で CLS 0.169 (Core Web Vitals の「要改善」帯、良好の閾値は 0.1) を計測し、「2 番目の見出しの手前」まで下げています。レイアウトシフトはそれが起きた瞬間に画面に映っているかで判定されるので、読者がまだスクロールしていない画面外で広告が膨らんでも、ファーストビューのスコアには入りません (先に見られてしまえば計上されるので、下げれば常に安全という話ではありません)。
対策として、枠に実寸相当の min-height を予約しておき、埋まらなかったときは :has() で枠ごと消しています。
.ad-slot-display {
min-height: 410px; /* ins 実寸 390px + 広告ラベル */
}
.ad-slot:has(> ins[data-ad-status='unfilled']) {
display: none;
}
/play/ には枠数ではなく回数の制限が入りました。表示は 1 ページロードにつき 2 マウントまで。「もう一度」で何周も遊ぶリピーターに毎回広告を出すのは、同じ人への過剰配信でクリック率と単価を下げるだけで、リピートというこのサイトの生命線と交換するものがないからです。
意外な角度から効いたのが教育現場ペルソナでした。指摘は「このサイトは閲覧者の端末を他人に手渡すゲームだから、パーソナライズ広告が他人の目に入る」というもので、学校利用で一発アウトになる政治・宗教を最優先でブロックしたうえで、「健全だが手渡し端末で気まずい」カテゴリ (転職、美容整形、消費者金融、占いなど) までブロック対象に足しています。
撤去の基準は入れる前に文書化しました。ゲーム紹介ページのヒーロー下枠は「あそぶ」への遷移率が相対 10% 超落ちたら撤去、/play/ の枠は「もう一度」率が落ちたら撤去です。審査に関わる判断もここに揃えています。
ads.txt は静的サイトなので public/ads.txt に置くだけ、自動広告は管理画面で OFF にしています (ON のままだと、どこに置かないかの設計をコード側の努力ごと Google が上書きします)。枠自体は承認前から本番に置いてあり、unfilled のときは折り畳まれて空白にならないので、審査に完成形を見せられます。
ハマった点: SSR がモジュール変数を消費して、枠が消えた
前の章の 2 マウント制限は、/play/ の実装でハマりました。モジュールスコープの let mountBudget = 2 で実装したところ、ビルドで事故りました。astro build は全ページを同一プロセスで描画するので、サーバー側レンダリング中にこのカウンタを減らすと、後からビルドされたページの静的 HTML から枠が消えます。実害は「当時 7 ゲームのうち 6 ページで、広告枠が静的 HTML に存在しない」+ ビルド順依存 + hydration mismatch の三点盛りでした。
let mountBudget = 2;
export function PlayAdSlot() {
const [visible] = useState(() => {
// SSR では予算を数えない: astro build は全 /play/ ページを同一プロセスで
// 描くので、ここでモジュール変数を消費すると後からビルドされたページの
// 静的 HTML から枠が消える (ビルド順依存 + hydration mismatch)。
// SSR が描くのは常に setup の 1 マウント目 = クライアント初回と一致する
if (typeof window === 'undefined') return true;
if (mountBudget <= 0) return false;
mountBudget--;
return true;
});
// 以下、visible のときだけ枠を描画し、ローダーを動的注入する
対処は「SSR では数えず、常に表示」です。これで安全な理由がきれいで、静的ビルドが描くのは常にセットアップ画面の 1 マウント目、つまりクライアントの初回マウントと必ず一致するからです。モジュールスコープの可変変数は、静的ビルドでは全ページの共有状態になる——これは SSG 全般で、広告以外でも踏める罠だと思います。
このレビューが効くのは、消す判断だ
5 つの専門家ペルソナは、新しい枠を追加してよいかの判断にはほとんど使いませんでした。効いたのは、既存の配置案を見せて「これは消すべきか」を判定させる場面です。撤去の判断は撤去後に何も起きないことを確認すれば裏付けが取れるのに対し、新規配置の承認は配信実績が出るまで正しかったかどうかが分かりません。確認しやすい判断のほうに、AI パネルは強く効くのだと考えています。
この効き方には前提があります。レビューの成否は、見せる現物の忠実さで決まりました。開発環境では広告が絶対に埋まらないため、枠にはプレースホルダーを出しますが、当初これが一律 160px でした。
160px 固定で出していたら、実寸 1,635px の枠を出荷前に誰も見つけられなかったはずです。ペルソナが優秀かどうかの前に、実寸の嘘をなくすことがレビューの前提条件でした。
いまはフォーマット別の実寸 (390 / 400 / 1,635px) でプレースホルダーを描画しています。恥ずかしい追伸として、記事内枠の予約も最初は 270px の過少予約——予約が防ぐはずだったものそのもの——をレビュー後の自分で踏み、実寸 + ラベルの 420px に直しています。
まとめ
5 つの専門家ペルソナは、枠を足すレビューではなく、消すレビューとして機能しました。効いたのはいつも撤去の可否を判定させる場面で、その効き方は見せる現物の忠実さに支えられています。この非対称性が承認判断にも本当に効くのかは、まだ確かめていません。次に試すとしたら、新しい配置案そのものをパネルに判定させてみることです。実際の配置は mawashite.com の紹介ページや記事ページでそのまま見られます (いまは審査中なので、枠は折り畳まれて見えないはずです)。