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

Next.js中引入Cookiebot脚本引发Hydration Error问题求助

解决Cookiebot脚本导致的Next.js水合错误

问题根源

Cookiebot脚本会在客户端动态插入<noscript>元素,但服务端渲染的初始HTML中不存在该元素,导致客户端水合阶段DOM结构不匹配,触发报错。另外,未完成同意/拒绝操作就刷新页面时,Cookiebot可能留存未完成的状态,既会导致横幅不再渲染,也会加剧水合冲突。生产环境下Next.js的优化策略(如更严格的HTML校验或脚本加载时机调整)掩盖了这个问题,但开发环境会直接暴露。

解决方案

方案1:用Next.js官方next/script组件加载脚本

next/script专为Next.js的SSR/SSG场景优化脚本加载,能从根源避免水合不匹配:

'use client'

import Script from 'next/script'

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html>
      <head>
        <Script
          id="Cookiebot"
          src="https://consent.cookiebot.com/uc.js"
          data-cbid="COOKIEBOT_ID"
          strategy="lazyOnload"
        />
        {/* 其他head内容 */}
      </head>
      <body>{children}</body>
    </html>
  )
}

选择lazyOnload策略可确保脚本在页面加载完成后执行,避免干扰初始渲染和水合。若需更早加载,也可使用afterInteractive策略,但lazyOnload的水合兼容性最优。

方案2:在useEffect中动态插入脚本

通过useEffect确保脚本仅在客户端加载,彻底避开服务端渲染的DOM不匹配问题:

'use client'

import { useEffect } from 'react'

export default function RootLayout({ children }: { children: React.ReactNode }) {
  useEffect(() => {
    const script = document.createElement('script')
    script.id = 'Cookiebot'
    script.src = 'https://consent.cookiebot.com/uc.js'
    script.setAttribute('data-cbid', 'COOKIEBOT_ID')
    script.async = true
    document.head.appendChild(script)

    return () => {
      document.head.removeChild(script)
    }
  }, [])

  return (
    <html>
      <head>
        {/* 其他head内容 */}
      </head>
      <body>{children}</body>
    </html>
  )
}

方案3:重置Cookiebot状态(可选)

若刷新后横幅仍不显示,可在脚本加载后强制重置状态,确保未操作时重新渲染横幅:

'use client'

import { useEffect } from 'react'

export default function RootLayout({ children }: { children: React.ReactNode }) {
  useEffect(() => {
    const loadCookiebot = () => {
      const script = document.createElement('script')
      script.id = 'Cookiebot'
      script.src = 'https://consent.cookiebot.com/uc.js'
      script.setAttribute('data-cbid', 'COOKIEBOT_ID')
      script.async = true
      script.onload = () => {
        if (window.Cookiebot) {
          window.Cookiebot.renew()
        }
      }
      document.head.appendChild(script)
    }

    loadCookiebot()

    return () => {
      const script = document.getElementById('Cookiebot')
      if (script) document.head.removeChild(script)
    }
  }, [])

  return (
    <html>
      <head>
        {/* 其他head内容 */}
      </head>
      <body>{children}</body>
    </html>
  )
}

window.Cookiebot.renew()会重置Cookiebot状态,强制重新检查用户授权,确保未操作的刷新后横幅正常显示。

效果验证

修改后在开发环境刷新页面(未点击同意/拒绝),水合错误应消失,Cookiebot横幅能正常渲染。生产环境不受影响,依然保持原有工作状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 08:22:38