You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

NextJS中Google Analytics与Adsense的Cookie合规集成问询

核心思路

不用直接移除 GTM,而是通过GTM 变量+触发器结合用户 Cookie 选择,精准控制代码加载:

  • Analytics:仅在用户同意分析类 Cookie 时触发采集
  • AdSense:区分两种模式——用户拒绝广告 Cookie 时加载非个性化广告,同意时加载个性化广告(无需移除广告)
  • 用 localStorage 持久化用户的 Cookie 选择,下次访问自动生效

创建上下文组件统一管理同意状态,并同步到 GTM 数据层:

// contexts/CookieConsentContext.js
import { createContext, useContext, useState, useEffect } from 'react';

const CookieConsentContext = createContext();

export function CookieConsentProvider({ children }) {
  const [consent, setConsent] = useState({
    analytics: false,
    advertising: false,
    isAccepted: false,
  });

  // 页面加载时读取本地存储的同意状态,并同步到GTM
  useEffect(() => {
    const saved = localStorage.getItem('cookieConsent');
    if (saved) {
      const parsed = JSON.parse(saved);
      setConsent(parsed);
      window.dataLayer?.push({
        event: 'consent_updated',
        user_consent_analytics: parsed.analytics,
        user_consent_advertising: parsed.advertising,
      });
    }
  }, []);

  // 更新同意状态并同步到GTM和本地存储
  const updateConsent = (newConsent) => {
    const updated = { ...consent, ...newConsent, isAccepted: true };
    setConsent(updated);
    localStorage.setItem('cookieConsent', JSON.stringify(updated));
    window.dataLayer?.push({
      event: 'consent_updated',
      user_consent_analytics: updated.analytics,
      user_consent_advertising: updated.advertising,
    });
  };

  return (
    <CookieConsentContext.Provider value={{ consent, updateConsent }}>
      {children}
    </CookieConsentContext.Provider>
  );
}

export function useCookieConsent() {
  return useContext(CookieConsentContext);
}

2. 在 _app.js 中集成 GTM 和上下文

GTM 始终加载,但内部标签根据同意状态触发:

// pages/_app.js
import { CookieConsentProvider } from '../contexts/CookieConsentContext';
import Script from 'next/script';
import CookieConsent from '../components/CookieConsent';

export default function MyApp({ Component, pageProps }) {
  return (
    <CookieConsentProvider>
      {/* GTM 脚本(始终加载) */}
      <Script
        id="gtm-script"
        strategy="afterInteractive"
        dangerouslySetInnerHTML={{
          __html: `
            (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
            new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
            j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
            'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
            })(window,document,'script','dataLayer','GTM-XYZ');
          `,
        }}
      />
      {/* GTM noscript 备用标签 */}
      <noscript>
        <iframe
          src="https://www.googletagmanager.com/ns.html?id=GTM-XYZ"
          height="0"
          width="0"
          style={{ display: 'none', visibility: 'hidden' }}
        ></iframe>
      </noscript>

      <Component {...pageProps} />
      <CookieConsent />
    </CookieConsentProvider>
  );
}

让用户自主选择 Cookie 类型:

// components/CookieConsent.js
import { useCookieConsent } from '../contexts/CookieConsentContext';

export default function CookieConsent() {
  const { consent, updateConsent } = useCookieConsent();

  if (consent.isAccepted) return null;

  return (
    <div style={{ 
      position: 'fixed', bottom: 0, left: 0, right: 0, 
      padding: '1.5rem', background: '#fff', boxShadow: '0 -2px 12px rgba(0,0,0,0.1)' 
    }}>
      <p style={{ margin: 0, marginBottom: '1rem' }}>
        我们使用 Cookie 优化体验和提供广告,您可以选择接受的类型。
      </p>
      <div style={{ display: 'flex', gap: '0.8rem', flexWrap: 'wrap' }}>
        <button onClick={() => updateConsent({ analytics: false, advertising: false })}>
          拒绝全部
        </button>
        <button onClick={() => updateConsent({ analytics: true, advertising: true })}>
          接受全部
        </button>
        <button onClick={() => updateConsent({ analytics: true, advertising: false })}>
          仅接受分析
        </button>
        <button onClick={() => updateConsent({ analytics: false, advertising: true })}>
          仅接受广告
        </button>
      </div>
    </div>
  );
}

4. 动态控制 AdSense 广告模式

创建 AdSense 组件,根据同意状态切换个性化/非个性化广告:

// components/AdSenseAd.js
import { useCookieConsent } from '../contexts/CookieConsentContext';
import { useEffect, useRef } from 'react';

export default function AdSenseAd({ adSlot, adClient }) {
  const { consent } = useCookieConsent();
  const adContainer = useRef(null);

  useEffect(() => {
    if (!adContainer.current) return;

    // 清空现有广告并创建新单元
    adContainer.current.innerHTML = '';
    const adElement = document.createElement('ins');
    adElement.className = 'adsbygoogle';
    adElement.style.display = 'block';
    adElement.setAttribute('data-ad-client', adClient);
    adElement.setAttribute('data-ad-slot', adSlot);
    adElement.setAttribute('data-ad-format', 'auto');
    adElement.setAttribute('data-full-width-responsive', 'true');
    // 关键:data-npa=true 表示非个性化广告,false 表示个性化
    adElement.setAttribute('data-npa', consent.advertising ? 'false' : 'true');

    adContainer.current.appendChild(adElement);

    // 加载AdSense脚本(仅首次执行)
    if (!window.adsbygoogle) {
      const script = document.createElement('script');
      script.src = 'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js';
      script.async = true;
      document.body.appendChild(script);
    }
    // 触发广告加载
    (window.adsbygoogle = window.adsbygoogle || []).push({});
  }, [consent.advertising, adSlot, adClient]);

  return <div ref={adContainer} />;
}

使用示例:

// 在页面中引入广告
<AdSenseAd adClient="ca-pub-XXXXXXXXXXXXXXXX" adSlot="YYYYYYYYYY" />

5. GTM 后台配置 Analytics

  1. 创建自定义变量:
    • 变量名:user_consent_analytics,类型:数据层变量,数据层变量名:user_consent_analytics
  2. 配置 GA4 标签:
    • 填入你的 Measurement ID,触发条件设置为:
      • 事件名称:consent_updated
      • 且 user_consent_analytics 等于 true
  3. 可选:添加页面视图触发器,同样设置为仅当 user_consent_analytics 为 true 时触发

关键注意事项

  • AdSense 账户获批后,替换组件中的 adClient 和 adSlot 为实际值
  • 非个性化广告无需用户同意,即使拒绝广告 Cookie 也会正常显示,仅不会基于用户兴趣投放
  • 分析类 Cookie 拒绝时,GTM 中的 GA 标签不会触发,不会收集用户行为数据

内容的提问来源于stack exchange,提问作者Korer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 18:27:35