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

Vite搭建React+TS项目用React-Router-Dom报document未定义错误

解决React Router + Vite SSR中document is not defined的问题

错误原因

你遇到的ReferenceError: document is not defined是因为服务器端渲染(SSR)环境下不存在浏览器的document对象,但createBrowserRouter是专为浏览器环境设计的,它初始化时会直接访问document,导致Node.js服务器运行时触发报错。

解决方案

方案1:将路由初始化移到客户端组件内部

修改App.tsx,把路由创建逻辑放到组件内部,通过useEffect确保仅在浏览器环境执行:

import { RouterProvider, createBrowserRouter } from "react-router-dom";
import RootLayout from "./pages/Root";
import HomePage from "./pages/HomePage";
import BookDetail from "./pages/BookDetail";
import { useEffect, useState } from "react";

function App() {
  const [router, setRouter] = useState(null);

  useEffect(() => {
    // 仅在浏览器环境中创建浏览器路由
    const browserRouter = createBrowserRouter([
      {
        path: "/",
        element: <RootLayout />,
        children: [
          { path: "/", element: <HomePage /> },
          { path: "/book/:id", element: <BookDetail /> },
        ],
      },
    ]);
    setRouter(browserRouter);
  }, []);

  // 服务器端渲染时返回null,避免执行浏览器专属代码
  if (!router) return null;

  return <RouterProvider router={router} />;
}

export default App;

方案2:使用React Router的SSR兼容路由方案

将路由配置抽离为共享文件,服务器端使用不依赖浏览器API的createMemoryRouter,客户端保持createBrowserRouter:

  1. 新建routes.ts共享路由配置
import RootLayout from "./pages/Root";
import HomePage from "./pages/HomePage";
import BookDetail from "./pages/BookDetail";

export const routes = [
  {
    path: "/",
    element: <RootLayout />,
    children: [
      { path: "/", element: <HomePage /> },
      { path: "/book/:id", element: <BookDetail /> },
    ],
  },
];
  1. 修改App.tsx(客户端)
import { RouterProvider, createBrowserRouter } from "react-router-dom";
import { routes } from "./routes";

// 客户端正常使用浏览器路由
const router = createBrowserRouter(routes);

function App() {
  return <RouterProvider router={router} />;
}

export default App;
  1. 修改entry-server.tsx(服务器端)
import React from 'react'
import ReactDOMServer from 'react-dom/server'
import { createMemoryRouter, RouterProvider } from 'react-router-dom'
import { routes } from './routes'

export function render() {
  // 服务器端使用内存路由,不依赖浏览器document
  const router = createMemoryRouter(routes, {
    initialEntries: ["/"], // 可根据实际请求路径动态调整
  });

  const html = ReactDOMServer.renderToString(
    <React.StrictMode>
      <RouterProvider router={router} />
    </React.StrictMode>
  )
  return { html }
}

额外说明

两种方案核心都是让浏览器专属的路由逻辑只在客户端执行,避免服务器端渲染时访问不存在的浏览器API。如果你的项目不需要SSR,也可以直接删除entry-server.tsx相关配置,转为纯客户端渲染,同样能解决该问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 04:35:27