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

实现Cookie弹窗点击控制Google Analytics与GTM的启用状态

实现基于Cookie同意的Google Analytics/Tag Manager加载控制

需求说明

需要实现Cookie同意页脚逻辑:

  • 点击「全部接受」:启用Google Analytics(GA)和Google Tag Manager(GTM)
  • 点击「仅必要」:仅启用GTM

分步解决方案

1. 完善Cookie状态区分与弹窗控制

修改FooterCookies组件,存储不同类型的同意状态,并在初始加载时检查已存在的Cookie避免重复弹窗:

import { useState, useEffect } from "react";
import Cookies from 'js-cookie'

function FooterCookies() {
  const [show, setShow] = useState(false);

  // 初始加载检查Cookie,无同意记录则显示弹窗
  useEffect(() => {
    const consent = Cookies.get('cookie_consent');
    if (!consent) setShow(true);
  }, []);

  const content = {
    text: '本网站使用Cookie优化体验并分析流量,你可以在我们的',
    policy: '隐私政策'中了解更多服务细节。'
  };

  // 设置对应类型的同意Cookie,并触发全局更新事件
  const setConsent = (type) => {
    Cookies.set('cookie_consent', type, { expires: 2 });
    setShow(false);
    window.dispatchEvent(new CustomEvent('cookieConsentUpdated', { detail: type }));
  };

  return (
    <>
      {show && (
        <div className=" h-auto bg-black/30 fixed bottom-0 text-cus-yellow rounded py-4 px-8 flex justify-evenly items-center z-[100] max75:flex-col max75:px-5 max75:py-3 max30:py-1 max30:px-1.5 max75:items-start">
          <div className=" w-85% max70:text-sm flex items-center max75:w-100% max75:items-start max75:mb-3 ">
            <p className=" text-[13px] pt-1">
              {content.text}
              <span className=" text-[16px] underline cursor-pointer ">
                {content.policy}
              </span>
            </p>
          </div>
          <div className=" flex ">
            <div 
              onClick={() => setConsent('accept_all')}
              className="border border-cus-yellow text-cus-yellow hover:bg-cus-yellow/60 transition-all hover:text-black w-28 h-80% bg-black/40 cursor-pointer flex flex-col justify-center items-center whitespace-nowrap duration-500 text-lg max75:text-base font-medium mx-2 px-1 py-2 max75:mx-0 max75:py-1 max75:px-0.5 "
            >
              全部接受
            </div>
            <div
              onClick={() => setConsent('necessary_only')}
              className="border border-cus-yellow text-cus-yellow hover:bg-cus-yellow/60 transition-all hover:text-black w-36 h-80% bg-black/40 cursor-pointer flex flex-col justify-center items-center whitespace-nowrap duration-500 text-lg max75:text-base font-medium mx-2 px-1 py-[13.76px] max75:mx-0 max75:ml-3 max75:px-0.5 max75:py-[8.75px] "
            >
              仅必要
            </div>
          </div>
        </div>
      )}
    </>
  );
}

export default FooterCookies;

2. 动态加载追踪脚本(修改MyApp.js)

移除固定加载的脚本,改为根据Cookie同意状态动态加载,同时监听同意更新事件:

import '../styles/globals.css';
import 'tailwindcss/tailwind.css';
import { useEffect, useState } from 'react';
import { useRouter } from 'next/router';
import Cookies from 'js-cookie';
import FooterCookies from './path-to-footer-cookies'; // 替换为实际组件路径
import * as gtag from '../lib/gtag';

function MyApp({ Component, pageProps }) {
  const router = useRouter();
  const [consentType, setConsentType] = useState(Cookies.get('cookie_consent'));

  // 监听同意更新事件,加载对应脚本
  useEffect(() => {
    const handleConsentUpdate = (e) => {
      setConsentType(e.detail);
      loadTrackingScripts(e.detail);
    };

    window.addEventListener('cookieConsentUpdated', handleConsentUpdate);
    
    // 初始加载时已有同意记录,直接加载脚本
    if (consentType) loadTrackingScripts(consentType);

    return () => window.removeEventListener('cookieConsentUpdated', handleConsentUpdate);
  }, [consentType]);

  // 路由变化时仅在全部同意状态下触发GA页面追踪
  useEffect(() => {
    const trackRoute = (url) => {
      if (consentType === 'accept_all') gtag.pageview(url);
    };

    router.events.on('routeChangeComplete', trackRoute);
    router.events.on('hashChangeComplete', trackRoute);

    return () => {
      router.events.off('routeChangeComplete', trackRoute);
      router.events.off('hashChangeComplete', trackRoute);
    };
  }, [router.events, consentType]);

  // 动态加载GTM/GA脚本
  const loadTrackingScripts = (type) => {
    // 加载GTM(必要脚本),避免重复加载
    if (!window.gtmLoaded) {
      const gtmScript = document.createElement('script');
      gtmScript.async = true;
      gtmScript.src = `https://www.googletagmanager.com/gtm.js?id=YOUR-GTM-ID`; // 替换为你的GTM ID
      document.body.appendChild(gtmScript);
      window.gtmLoaded = true;
      window.dataLayer = window.dataLayer || [];
      window.dataLayer.push({'gtm.start': new Date().getTime(), event:'gtm.js'});
    }

    // 全部同意时加载GA
    if (type === 'accept_all' && !window.gaLoaded) {
      const gaScript = document.createElement('script');
      gaScript.async = true;
      gaScript.src = `https://www.googletagmanager.com/gtag/js?id=${gtag.GA_TRACKING_ID}`;
      document.body.appendChild(gaScript);
      
      gaScript.onload = () => {
        window.dataLayer = window.dataLayer || [];
        function gtag(){dataLayer.push(arguments);}
        gtag('js', new Date());
        gtag('config', gtag.GA_TRACKING_ID, { page_path: window.location.pathname });
        window.gaLoaded = true;
      };
    }
  };

  return (
    <>
      <Component {...pageProps} />
      <FooterCookies />
    </>
  );
}

export default MyApp;

3. 清理Document.js中的重复脚本

移除Document.js中重复的GTM/GA脚本,仅保留noscript的GTM iframe:

import { Html, Head, Main, NextScript } from 'next/document';

export default function Document() {
  return (
    <Html>
      <Head>
        {/* 移除重复的GTM/GA脚本 */}
      </Head>
      <body>
        <noscript
          dangerouslySetInnerHTML={{
            __html: `<iframe src="https://www.googletagmanager.com/ns.html?id=YOUR-GTM-ID"
            height="0" width="0" style="display:none;visibility:hidden" />`,
          }}
        />
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}

核心逻辑说明

  • 用cookie_consent字段存储用户同意类型,值为accept_all或necessary_only
  • GTM作为必要脚本,无论哪种同意都会加载;GA仅在「全部接受」时加载
  • 通过自定义事件cookieConsentUpdated实现组件间状态同步
  • 初始加载检查Cookie,避免重复显示同意弹窗

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 04:20:22