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

React SSR运行报ReferenceError: document is not defined错误如何解决?

错误原因
  • 核心问题是Node.js服务端环境不存在浏览器专属的document全局对象,代码里两处触发了该对象调用:
    1. 路由层面:App.js中直接全局使用了BrowserRouter,其底层依赖的createBrowserHistory方法会调用document相关API,服务端执行renderToString渲染App组件时直接触发报错
    2. 构建配置层面:webpack.server.js中针对css使用了style-loader,该loader的逻辑是动态往document.head插入style标签,服务端执行时同样会找不到document报错
  • 额外兼容问题:当前使用的是react-router-dom v6版本,现有App.js里的Route写法不符合v6规范,component属性已废弃,需改为element属性传组件实例。
修复步骤

1. 路由逻辑拆分

修改App.js,移除内部的BrowserRouter包裹,调整Route写法

import React from 'react';
import { Route, Routes, Link} from "react-router-dom";

import Home from './Home';
import About from './About';

export default () => {
  return ( 
    <>
      <nav>
          <Link to="/"> Home </Link>
          <Link to="/about"> About </Link>
          <Link to="/product"> Product </Link>
      </nav>    
       <Routes>
         <Route exact path="/" element={<Home />} />
         <Route path="/about" element={<About />} />      
       </Routes>
    </>
  );
};

修改客户端index.js,用BrowserRouter包裹App

import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { BrowserRouter as Router } from "react-router-dom";

ReactDOM.hydrate(
  <React.StrictMode>    
    <Router>
      <App />
    </Router>
  </React.StrictMode>,
  document.getElementById("root")
);

修改服务端渲染逻辑(server/index.js),用StaticRouter包裹App

服务端渲染时需要拿到当前请求的path传给StaticRouter的location属性,示例代码:

import { StaticRouter } from 'react-router-dom/server';
// 其他依赖引入逻辑省略
app.get('/*', (req, res) => {
  const appHtml = ReactDOMServer.renderToString(
    <StaticRouter location={req.path}>
      <App />
    </StaticRouter>
  )
  // 后续拼接完整HTML返回的逻辑省略
})

2. 修复服务端webpack配置

安装mini-css-extract-plugin,替换掉服务端css规则里的style-loader:

const path = require('path');
const nodeExternals = require('webpack-node-externals');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
  entry: './server/index.js',
  target: 'node',
  externals: [nodeExternals()],
  output: {
    path: path.resolve('server-build'),
    filename: 'index.js'
  },
  mode: 'development',
  module: {
    rules: [
      {
        test: /\.js|jsx$/,
        use: 'babel-loader',
        exclude: /(node_modules|bower_components)/,
      },
      {
        test: /\.css$/i,
        use: [MiniCssExtractPlugin.loader, "css-loader"],
      },
      {
        test: /\.link\.css$/i,
        use: [
          { loader: "style-loader", options: { injectType: "linkTag" } },
          { loader: "file-loader" },
        ],
      },
    ]
  },
  plugins: [new MiniCssExtractPlugin()]
};

如果需要实现同构样式也可以选择isomorphic-style-loader,根据自身业务场景选择即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 14:24:01