如何在Next.js中实现Osano CookieConsent并解决window未定义报错
ReferenceError: window is not defined 报错的核心原因是Next.js默认开启服务端渲染/静态生成逻辑,而Osano CookieConsent是纯浏览器端运行的插件,依赖window、document等浏览器专属全局对象,你在组件顶层直接require该库时,服务端执行渲染逻辑就会因为找不到window对象触发报错。
以下是两种可行的实现方案:
方案1:useEffect内动态导入(改动最小)
直接删除组件顶层的const CC = require( "CookieConsent")代码,在useEffect中通过动态导入的方式加载库,useEffect仅会在客户端执行,避免服务端运行逻辑:
import { useEffect } from 'react' export default function Home() { useEffect(() => { // 仅客户端执行时加载插件 const initCC = async () => { const CookieConsent = (await import('cookieconsent')).default const cc = new CookieConsent({ container: document.getElementById("cookieconsent"), palette: { popup: { background: "#1aa3ff" }, button: { background: "#e0e0e0" }, }, revokable: true, onStatusChange: function(status) { console.log(this.hasConsented() ? 'enable cookies' : 'disable cookies'); }, position: "bottom-left", theme: "classic", domain: "<替换为你的应用域名>", secure: true, content: { header: 'Cookies used on the website!', message: 'This website uses cookies to improve your experience.', dismiss: 'Got it!', allow: 'Allow cookies', deny: 'Decline', link: 'Learn more', href: 'https://www.cookiesandyou.com', close: '❌', policy: 'Cookie Policy', target: '_blank', } }) } initCC() }, []) return ( // 你的页面其他代码 <div id="cookieconsent"></div> ) }
方案2:封装为独立组件并禁用SSR
如果需要在多个页面复用该插件,可以将逻辑封装为独立组件,通过next/dynamic关闭组件的服务端渲染:
- 新建
components/CookieConsent.jsx文件:
import { useEffect } from 'react' const CC = require('cookieconsent') export default function CookieConsent() { useEffect(() => { const cc = new CC({ // 此处填写你原有配置即可,和方案1的配置完全一致 container: document.getElementById("cookieconsent"), // ...其余配置项 }) }, []) return <div id="cookieconsent"></div> }
- 在页面中导入组件时禁用SSR:
import dynamic from 'next/dynamic' // 关闭组件的服务端渲染 const CookieConsent = dynamic(() => import('../components/CookieConsent'), { ssr: false }) export default function Home() { return ( // 你的页面其他代码 <CookieConsent /> ) }
注意事项
- 确保已经安装了对应依赖:
npm install cookieconsent - 如果插件样式不生效,在
_app.js顶层导入插件的样式文件即可:import 'cookieconsent/build/cookieconsent.min.css'
内容的提问来源于stack exchange,提问作者kuriouskoala
相关产品推荐
相关产品推荐

