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

如何让Usercentrics Cookiebot在Next.js v14(App Router)中正常工作

解决Next.js集成Cookiebot的React错误#418及脚本加载问题

问题分析

  1. React错误#418:Cookiebot的data-blockingmode="auto"会自动修改DOM元素,和Next.js的hydration(水合)过程冲突,导致React检测到DOM不匹配触发报错,同时横幅因DOM被干扰短暂显示后消失。
  2. next/script方案失败:大概率是属性传递错误、策略选择不当,或是CBID(Cookiebot ID)未正确替换导致脚本找不到。

解决方案

方案1:使用next/script正确集成(推荐)

Next.js的next/script组件专门优化外部脚本加载,需注意以下细节:

  • uc.js必须设置id="Cookiebot",且用beforeInteractive策略确保页面初始化时加载。
  • 所有data-*属性直接作为props传递给Script组件。
  • 替换所有<id here>为你的真实Cookiebot CBID。
import { Script } from 'next/script';
import { isProduction } from '@/utils/env'; // 替换为你的环境判断函数

export default function RootLayout({ children }: { children: React.ReactNode }) {
  const CBID = '你的真实Cookiebot ID'; // 替换成实际ID

  return (
    <html lang="en">
      <head>
        <link rel="icon" href="/favicon.svg" />
        {isProduction() && (
          <Script
            id="Cookiebot"
            src="https://consent.cookiebot.com/uc.js"
            data-cbid={CBID}
            data-blockingmode="auto"
            strategy="beforeInteractive"
          />
        )}
      </head>
      <body className={`${urbanist.className} flex flex-col`}>
        <Providers>
          {children}
          <Analytics />
        </Providers>
        {isProduction() && (
          <Script
            id="CookieDeclaration"
            src={`https://consent.cookiebot.com/${CBID}/cd.js`}
            strategy="afterInteractive"
            async
          />
        )}
      </body>
    </html>
  );
}

方案2:修复原生script的hydration冲突

如果坚持使用原生script,需避免在hydration过程中让Cookiebot修改DOM:

  • 将data-blockingmode="auto"改为data-blockingmode="manual",避免自动操作DOM。
  • 在客户端hydration完成后再加载脚本,用useEffect实现(仅在客户端执行)。
'use client'; // 必须添加,useEffect为客户端钩子
import { useEffect } from 'react';
import { isProduction } from '@/utils/env';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  const CBID = '你的真实Cookiebot ID';

  useEffect(() => {
    if (!isProduction()) return;

    // 加载uc.js
    const ucScript = document.createElement('script');
    ucScript.id = 'Cookiebot';
    ucScript.src = 'https://consent.cookiebot.com/uc.js';
    ucScript.setAttribute('data-cbid', CBID);
    ucScript.setAttribute('data-blockingmode', 'auto');
    document.head.appendChild(ucScript);

    // 加载CookieDeclaration脚本
    const cdScript = document.createElement('script');
    cdScript.id = 'CookieDeclaration';
    cdScript.src = `https://consent.cookiebot.com/${CBID}/cd.js`;
    cdScript.async = true;
    document.body.appendChild(cdScript);

    // 清理函数
    return () => {
      ucScript.remove();
      cdScript.remove();
    };
  }, []);

  return (
    <html lang="en">
      <head>
        <link rel="icon" href="/favicon.svg" />
      </head>
      <body className={`${urbanist.className} flex flex-col`}>
        <Providers>
          {children}
          <Analytics />
        </Providers>
      </body>
    </html>
  );
}

额外注意事项

  • 确保isProduction()函数正确判断环境,避免在开发环境加载生产脚本。
  • 检查CBID是否正确,登录Cookiebot后台可获取专属ID。
  • 不要同时使用原生script和next/script加载Cookiebot脚本,会导致冲突。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 08:57:24