如何在 Next.js 项目中正确集成并使用 Bootstrap 5?
ReferenceError: document is not defined报错的核心原因是Next.js默认支持服务端渲染,服务端环境不存在document全局对象,而Bootstrap 5的JS模块依然是针对原生浏览器环境设计的,直接全局导入会在服务端渲染阶段执行报错。同时Bootstrap的原生JS逻辑没有适配React的虚拟DOM更新机制,直接使用data-bs-*属性在组件重新渲染时可能出现状态不同步的问题。
以下是三种可行的集成方案:
方案1:客户端侧导入Bootstrap全量JS
这是改动最小的方案,只需调整/pages/_app.js的导入逻辑,利用useEffect仅在客户端执行的特性加载Bootstrap JS,无需修改现有组件代码:
import 'bootstrap/dist/css/bootstrap.css' import { useEffect } from 'react' export default function App({ Component, pageProps }) { useEffect(() => { // 仅在客户端导入Bootstrap JS,跳过服务端执行阶段 import('bootstrap/dist/js/bootstrap.js') }, []) return <Component {...pageProps} /> }
方案2:按需初始化Bootstrap组件实例
如果不需要用到所有Bootstrap JS组件,可以按需初始化对应组件,减少冗余代码加载,以Collapse组件为例:
import { useEffect, useRef } from 'react' import { Collapse } from 'bootstrap' function CollapseDemo() { const collapseRef = useRef(null) useEffect(() => { // 客户端手动初始化Collapse实例 new Collapse(collapseRef.current) }, []) return ( <div> <p> <a className="btn btn-primary" data-bs-toggle="collapse" href="#collapseExample" role="button" aria-expanded="false" aria-controls="collapseExample"> Link with href </a> <button className="btn btn-primary" type="button" data-bs-toggle="collapse" data-bs-target="#collapseExample" aria-expanded="false" aria-controls="collapseExample"> Button with data-bs-target </button> </p> <div className="collapse" id="collapseExample" ref={collapseRef}> <div className="card card-body"> Some placeholder content for the collapse component. This panel is hidden by default but revealed when the user activates the relevant trigger. </div> </div> </div> ) } export default CollapseDemo
注意React中需要把原生HTML的class属性改为className,避免属性识别警告。
方案3:使用适配React的Bootstrap 5封装库
不需要退回到仅支持Bootstrap 4的reactstrap,目前react-bootstrap的v2及以上版本已经完全适配Bootstrap 5,符合React的声明式开发逻辑,不需要手动处理DOM实例,和Next.js的SSR/SSG特性兼容度最高,是长期维护项目的更优选择。
内容的提问来源于stack exchange,提问作者DavidPH
相关产品推荐
相关产品推荐

