はじめに
Google Consent Mode v2 は、ユーザーのCookie同意状態に応じてGA4やGoogle広告のデータ収集を制御する仕組みです。2024年3月からEEA向けに必須化されましたが、日本の改正電気通信事業法への対応としても有効です。
本記事では、Next.js 15 App Routerで Google Consent Mode v2 を正しく実装する方法を、実際のプロダクト(Bitcoin Simulator)のコードをベースに解説します。
Google Consent Mode v2 とは
Consent Mode v2 では、以下の4つの同意パラメータを管理します。
| パラメータ | 用途 |
|---|---|
analytics_storage |
GA4のCookie |
ad_storage |
広告Cookie |
ad_user_data |
広告目的のユーザーデータ送信 |
ad_personalization |
広告パーソナライゼーション |
重要なのは、GA4スクリプトを読み込む前に gtag('consent', 'default', ...) を呼び出すことです。
実装の全体像
Next.js App Routerでの実装は3ステップです。
- Cookie同意バナーで同意レベルを取得・保存
- GA4コンポーネントで Consent Mode default/update を発行
- 同意変更イベントでリアルタイムに状態を更新
ステップ1: Cookie同意の管理
まず、Cookie同意の状態を管理する仕組みを作ります。
export function getConsentLevel(): 'all' | 'essential' | null {
try {
const val = localStorage.getItem('cookie_consent');
if (val === 'all' || val === 'essential') return val;
if (val === '1') {
localStorage.setItem('cookie_consent', 'all');
return 'all';
}
} catch { /* storage unavailable */ }
return null;
}
同意変更時にはカスタムイベントを発火します。
function handleAccept(level: 'all' | 'essential') {
localStorage.setItem('cookie_consent', level);
window.dispatchEvent(new Event('cookie-consent-changed'));
}
ステップ2: GA4コンポーネントにConsent Modeを統合
ここが本記事の核心です。
'use client';
import { useEffect, useRef } from 'react';
import { getConsentLevel } from './cookie-consent';
const GA_ID = process.env.NEXT_PUBLIC_GA_MEASUREMENT_ID;
function gtag(...args: unknown[]) {
window.dataLayer = window.dataLayer || [];
window.dataLayer.push(args);
}
export default function GoogleAnalytics() {
const loaded = useRef(false);
const consentDefaultSet = useRef(false);
useEffect(() => {
if (!GA_ID) return;
if (!consentDefaultSet.current) {
consentDefaultSet.current = true;
const ok = getConsentLevel() === 'all';
gtag('consent', 'default', {
analytics_storage: ok ? 'granted' : 'denied',
ad_storage: 'denied',
ad_user_data: 'denied',
ad_personalization: 'denied',
});
}
const load = () => {
if (loaded.current) return;
if (getConsentLevel() !== 'all') return;
loaded.current = true;
gtag('consent', 'update', { analytics_storage: 'granted' });
const s = document.createElement('script');
s.src = 'https://www.googletagmanager.com/gtag/js?id=' + GA_ID;
s.async = true;
document.head.appendChild(s);
gtag('js', new Date());
gtag('config', GA_ID, { anonymize_ip: true });
};
load();
window.addEventListener('cookie-consent-changed', load);
return () => window.removeEventListener('cookie-consent-changed', load);
}, []);
return null;
}
実装のポイント
1. default は GA スクリプトより前に
gtag('consent', 'default', ...) はdataLayerへのpushなので、GAスクリプト読み込み前に実行できます。
2. useRefで重複防止
React 18のStrict Modeでのダブル実行を防止します。
3. 同意前はスクリプト自体を読み込まない
Consent Mode の denied 設定だけでなく、スクリプト読み込み自体を制御します。
4. cookie-consent-changed イベント
同意バナーで許可した瞬間にページリロードなしでGA4が有効化されます。
Root Layoutへの配置
<body>
{children}
<CookieConsent />
<GoogleAnalytics />
</body>
まとめ
-
consent defaultをGAスクリプト読み込み前に発行 - 同意取得後に
consent update+ スクリプト読み込み - カスタムイベントで同意変更をリアルタイム反映
この実装は Bitcoin Simulator で実際に稼働しているコードをベースにしています。