Next.js 13+ App Router 中应避免在服务端组件直接导入 Bootstrap JS,CSS 可安全 SSR 导入;JS 组件需在 'use client' 组件中用 useEffect + 动态 import 初始化,或改用 react-bootstrap 实现开箱即用的 SSR/CSR 兼容。
Next.js 13+ App Router 中直接 import Bootstrap CSS 会报错
next.js 的 app router 默认使用服务端渲染(ssr),而 bootstrap 的 css 文件里包含大量依赖 window 或 document 的 js 初始化逻辑(比如 dropdown、modal),直接在 layout.tsx 或 page.tsx 里 import 'bootstrap/dist/css/bootstrap.min.css' 会导致构建失败或运行时报 referenceerror: window is not defined。
正确做法是把 CSS 导入限制在客户端环境:
- 在
app/layout.tsx中仅导入纯 CSS(无 JS)——但注意:Bootstrap 官方的bootstrap.min.css是安全的,它不包含 JS,可放心 SSR 导入 - 所有带交互的 JS 组件(如
Modal、Toast)必须用'use client'标记,并延迟初始化 - 不要在服务端组件中
import 'bootstrap'或import 'bootstrap/dist/js/bootstrap.bundle.min.js'
如何在 Client Component 中安全使用 Bootstrap JS 组件
Bootstrap 的 JS 插件(如 Offcanvas、Tooltip)需要 DOM 就绪后手动实例化,不能靠全局 script 标签自动触发。Next.js 的 Client Component 渲染时机和 DOM 挂载顺序必须显式控制。
推荐方式是用 useEffect + ref 延迟初始化:
'use client'
import { useEffect, useRef } from 'react'
export default function MyTooltip() {
const tooltipRef = useRef(null)
useEffect(() => {
if (typeof window === 'undefined') return
import('bootstrap/dist/js/bootstrap.bundle.min.js').then(({ Tooltip }) => {
Tooltip.getOrCreateInstance(tooltipRef.current)
})
}, [])
return (
<button ref={tooltipRef} data-bs-toggle="tooltip" title="Hello">
Hover me
</button>
)
}
- 必须加
if (typeof window === 'undefined') return防止 SSR 时执行 - 用
import()动态导入 JS,避免打包进服务端 bundle - 不要在
useEffect外调用new Tooltip(...),否则会报找不到 DOM 节点
使用 react-bootstrap 替代原生 Bootstrap JS 更省心
原生 Bootstrap JS 和 Next.js 的生命周期耦合太紧,容易出错。更稳妥的选择是用 react-bootstrap —— 它是专为 React 设计的封装,完全兼容 SSR 和 Client Components,且不依赖全局 data-bs-* 属性。
安装与使用:
npm install react-bootstrap bootstrap
然后在 app/layout.tsx 顶部导入 CSS(SSR 安全):
import 'bootstrap/dist/css/bootstrap.min.css'
在任意 Client Component 中直接使用:
'use client'
import { Button, Tooltip, OverlayTrigger } from 'react-bootstrap'
export default function Demo() {
return (
<OverlayTrigger
overlay={<Tooltip id="tip">Works without manual init</Tooltip>}
>
<Button variant="primary">Hover</Button>
</OverlayTrigger>
)
}
-
react-bootstrap内部已处理好挂载/卸载逻辑,无需useEffect手动管理 - 组件 props 代替
data-bs-*,类型安全,IDE 支持好 - 注意:仍需在 layout 中导入 CSS,否则样式丢失
自定义 Bootstrap 主题(SCSS)在 Next.js 中编译失败怎么办
想改 $primary 颜色或禁用部分组件?直接在 Next.js 里 @import 'bootstrap/scss/bootstrap' 会报 SassError: Can't find stylesheet to import —— 因为 Next.js 默认不处理 .scss 中的 @import 别名(如 ~bootstrap/scss/functions)。
解决路径只有两条:
- 用
alias配置让 Sass 解析器认识~:在next.config.js中加sassOptions.alias,指向node_modules/bootstrap/scss - 更简单:放弃
@import,改用@use(Dart Sass 推荐语法),并显式写全路径:@use 'bootstrap/scss/functions' with ($primary: #2563eb) - 别漏掉
bootstrap/scss/variables必须在functions之后、bootstrap之前@use,否则变量覆盖无效
真正容易被忽略的是:SCSS 编译后的 CSS 必须仍通过 layout.tsx 导入,不能放在组件里 —— 否则样式不会全局生效。


















