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

在Next.js 14.1.0中导入Bootstrap 5.3.2出现document未定义错误

解决Next.js 14.1.0 App Router中Bootstrap 5.3.2组件SSR时document is not defined的问题

问题现象

硬刷新页面时触发500错误,控制台报错:

⨯ node_modules/bootstrap/dist/js/bootstrap.esm.js (803:18) @ document
⨯ ReferenceError: document is not defined
    at __webpack_require__ (/Users/rsilva/Desktop/bs/.next/server/webpack-runtime.js:33:42)
    at eval (./app/TooltipComponent.js:9:67)
    at (ssr)/./app/TooltipComponent.js (/Users/rsilva/Desktop/bs/.next/server/app/page.js:162:1)
    at __webpack_require__ (/Users/rsilva/Desktop/bs/.next/server/webpack-runtime.js:33:42)

问题原因

虽然TooltipComponent添加了"use client"指令,但模块顶部的import { Tooltip } from "bootstrap"会在**服务端渲染(SSR)**阶段被执行。Bootstrap的ESM模块加载时会直接访问浏览器特有的document对象,而Node.js服务端环境不存在该对象,导致报错。

解决方案

方案1:在客户端 useEffect 中动态导入Tooltip

修改TooltipComponent,将Bootstrap的Tooltip导入和实例化逻辑移到客户端的useEffect中,确保仅在浏览器环境执行:

"use client";

import { useEffect, useRef } from "react";

export function TooltipComponent({
  children,
  title = "Missing tooltip 'title' property",
  placement = "top",
  trigger = "hover",
}) {
  const tooltipRef = useRef();
  const tooltipInstanceRef = useRef(null);

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

    async function initTooltip() {
      // 仅在客户端动态导入Bootstrap Tooltip
      const { Tooltip } = await import("bootstrap/dist/js/bootstrap.esm.js");
      tooltipInstanceRef.current = new Tooltip(tooltipRef.current, {
        title,
        placement,
        trigger,
        container: "body",
      });
    }

    initTooltip();

    return () => {
      // 组件卸载时销毁Tooltip实例
      if (tooltipInstanceRef.current) {
        tooltipInstanceRef.current.dispose();
      }
    };
  }, [title, placement, trigger]);

  return <span ref={tooltipRef}>{children}</span>;
}

方案2:使用Next.js动态导入禁用SSR

如果需要对整个组件禁用服务端渲染,可在page.js中通过dynamic导入组件:

import dynamic from 'next/dynamic';

// 禁用该组件的SSR,仅在客户端加载
const TooltipComponent = dynamic(
  () => import('./TooltipComponent').then(mod => mod.TooltipComponent),
  { ssr: false }
);

export default function Home() {
  return (
    <main>
      <TooltipComponent title="Test">
        test tooltip
      </TooltipComponent>
    </main>
  );
}

补充说明

  • 原BootstrapProvider可保留,它负责将Bootstrap挂载到window对象上,与上述方案不冲突;若仅使用动态导入的Tooltip,也可移除该Provider。
  • 核心思路是确保Bootstrap的JS代码仅在浏览器环境执行,避免服务端渲染时访问浏览器专属API。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 07:27:06