Image Source: statics.mylandingpages.co
「全ページに出るはずのポップアップが、なぜか出ない」。まずは5分で一次切り分け、その後30分で深掘りして確実に復旧させましょう。本稿は実務で再現できる検証→是正→再検証の流れに絞っています。
まずは5分で一次切り分け(最短ルート)
- シークレットウィンドウで再現し、拡張(AdBlock等)を一時無効化して比較。
- Chrome DevToolsのNetworkで、ポップアップ関連のJS/iframeが「取得できているか」「誰が呼んだか(Initiator)」「ブロック理由」を確認。手順は公式の「DevTools Networkの使い方」が参考になります。
- ConsoleでCSP違反やMixed Content、JSエラーの有無を確認。
- Elements/Computedで対象要素がDOMに存在するか、z-index/position/transform/opacity等で埋没していないかを確認。スタッキングの基礎は「MDN: Stacking context」が詳しいです。
- GTMプレビューモード/デバッグツールで、トリガ(スクロール・タイマー・Exit-intent等)が実際に一致しているかを見る。
30分で深掘り診断(5つの観点で原因を潰す)
1) 可視性(CSS/スタッキング)
- 症状: DOMにはあるのに見えない/背面に隠れている/画面外に描画されている。
- 検証: Elementsでポップアップ要素を選択し、position/z-index/transform/opacity/isolation、親要素のtransformやfilterの有無をチェック。
- 是正: モーダルをbody直下にレンダリング(Portal等)、position: fixed/absoluteを明示、高めのz-index、親の不要なtransformを除去。スタッキングの原理は前掲の「MDN: Stacking context」が基礎になります。
2) 配信(Network/CSP/iframe)
- 症状: スクリプトやiframe自体が読み込まれていない/CSPやsandboxで拒否される。
- 検証: NetworkでHTTPステータス、Initiator、Blocked Reasonを確認。Consoleに「Refused to…」等のCSP違反ログがないかを確認。
- 是正: 必要な送信先をCSPで許可。特に埋め込み側/埋め込まれ側の関係で、frame-ancestorsの制約が原因になることがあるため、「MDN: CSP frame-ancestors」の要件を満たしているかを見直す。iframeのsandboxを使う場合は許可トークン(allow-scripts等)を適切に付与。
3) 条件(トリガ/頻度/ターゲティング)
- 症状: 特定ページ・端末だけ出ない/初回・再訪で挙動が変わる。
- 検証: GTMプレビューでトリガ一致と変数値(URLパターン、スクロール量、滞在秒、端末/言語/地域)を確認。頻度キャップや「一度閉じたら出さない」設定がCookie/Storageに依存していないかを確認。
- 是正: 条件を一時的に緩和して再現性を確保、想定ページ範囲やデバイス条件を整理。実装がSPAなら、History Changeやカスタムイベントに合わせて表示ロジックを発火させる。GA4のSPA測定は「GA4: Single Page Applications」を参照。
4) ブロック(AdBlock/ITP/ブラウザ保護機能)
- 症状: Safariだけ出ない、拡張機能を無効化すると出る、社内ネットワークだけNG。
- 検証: シークレット+拡張OFF、別ブラウザ(Safari/Firefox)の比較。ITPの影響はCookie/localStorage等の保持期間や分類に左右されます。
- 是正: 頻度制御や識別をサードパーティCookie/Storageに依存しない設計へ。サーバサイド記録や1st-party化を検討。ITPの方向性はWebKit一次情報(例示含む)で確認できます。参考: 「WebKit Blog: Meet Declarative Web Push」(ITPによるデータ保持の考え方に触れています)。
5) エラー(Console/Cookie/Consent)
症状と対処の早見表
| 症状 | 想定原因 | 検証ポイント | 是正の方向 |
| DOMにあるのに見えない | z-index/スタッキング、親transform | Elements/Computedでposition・z-index・transform・opacity | body直下に描画、position明示、高z-index、親のtransform削除 |
| そもそも読み込まれない | Network失敗、CSP/sandbox制約 | NetworkのStatus/Initiator/Blocked Reason、ConsoleのCSP違反 | CSPに必要送信先を許可、sandbox許可の見直し、URL/バージョン確認 |
| 特定環境だけ出ない | Safari ITP、拡張機能、社内制限 | シークレット/別ブラウザ/別回線で比較 | 1st-party化、サーバ側記録、Storage依存を最小化 |
| 条件が噛み合わない | トリガ/頻度/ターゲティング | GTMプレビューの一致と変数値 | 条件緩和と再設計、SPAはHistory/イベントで発火 |
| 同意やCookie周りで不一致 | SameSite属性不足、Consent未取得 | ApplicationでCookie属性、CMPで同意状態 | HTTPS+SameSite=None; Secure、同意後初期化・匿名化フォールバック |
SPA・Consent・Cookie・ITPの落とし穴(設計の要点)
- SPA: 初回ロード後のURL変化は「ページ遷移扱い」ではないことが多い。History ChangeやdataLayer.pushで仮想PV/イベントを送り、ポップアップの表示条件も同じトリガに寄せる。実装の考え方は「GA4: Single Page Applications」。
- Consent Mode v2: ad_storage/analytics_storage等の同意ステータスによりタグの挙動が変わる。未同意時は送信が抑制されたり匿名化に切り替わるため、CMPで同意後に初期化する流れを組む。仕様は「Google: Consent(Tag Platform)」。
- Cookie/SameSite: クロスサイトが関与する頻度制御はSameSite=None; Secure(HTTPS必須)に統一。「web.dev: SameSite Cookies」を参照。
- ITP: Safariではトラッカー分類やユーザー相互作用の有無でデータ保持に制限。クッキー/Storage頼みの頻度キャップは破綻しやすいので、1st-party・サーバ側での制御へ。一次情報の方向性は「WebKit Blogの該当記事」を手掛かりに。
再発防止のベストプラクティス
- モーダルはbody直下に描画し、position/z-indexを明示。親のtransformやoverflowを最小化。
- スクリプトはdefer、依存順序を固定。CDNパスとバージョンを管理し、CSPはReport-Onlyで検証→本番適用。
- SPAはHistory Changeや専用イベントで「表示条件」と「計測」を同一設計にし、重複/欠損を防ぐ。
- 同意管理はCMPと連携し、未同意時は匿名化/遅延表示にフォールバック。
- クロスサイトCookieが要る機能はHTTPS+SameSite=None; Secureを徹底。Safariは1st-party/サーバ側で頻度制御。
次のステップ(運用ドキュメントの整備)
復旧したら、手順書とチェックリストを整備して再発を防ぎましょう。記事化・共有の効率化には、自社ブログでノウハウをストックしておくのが近道です。Disclosure: QuickCreator is our product. ナレッジの作成と多言語公開に活用できます: QuickCreator
補助リンク(学習を深めたい方向け)