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

如何在React项目中实现Server-Side Rendering(SSR)以优化SEO?

React SSR 完整搭建指南(含hydrateRoot修复方案)

一、项目初始化与依赖安装

首先初始化项目并安装核心依赖:

mkdir react-ssr-demo && cd react-ssr-demo
npm init -y
npm install express react react-dom
# 若使用ES模块,在package.json中添加 "type": "module"

二、服务端渲染核心实现

创建server.js,负责处理HTTP请求并返回服务端渲染的HTML:

import express from 'express';
import React from 'react';
import { renderToString } from 'react-dom/server';
import App from './src/App.jsx';

const app = express();
const PORT = 3000;

// 托管客户端打包后的静态资源
app.use(express.static('dist'));

// 处理所有路由请求
app.get('*', (req, res) => {
  // 将React组件渲染为HTML字符串
  const appHtml = renderToString(<App />);

  // 构建完整HTML模板,注入渲染后的组件内容
  const html = `
    <!DOCTYPE html>
    <html lang="zh-CN">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>React SSR Demo</title>
        <meta name="description" content="服务端渲染的React应用,提升SEO">
      </head>
      <body>
        <div id="root">${appHtml}</div>
        <!-- 引入客户端hydrate脚本 -->
        <script type="module" src="/client.js"></script>
      </body>
    </html>
  `;

  res.send(html);
});

app.listen(PORT, () => {
  console.log(`Server running on http://localhost:${PORT}`);
});

三、客户端hydrateRoot正确配置

创建src/client.jsx,负责将服务端渲染的静态HTML激活为可交互的React应用:

import React from 'react';
import { hydrateRoot } from 'react-dom/client';
import App from './App.jsx';

// 必须使用服务端渲染时生成的根节点
const rootElement = document.getElementById('root');

// 执行hydrate,而非render,保留服务端渲染的DOM结构
hydrateRoot(rootElement, <App />);

四、核心业务组件(src/App.jsx)

确保服务端与客户端使用同一个组件,避免DOM结构差异:

import React from 'react';

function App() {
  // 注意:服务端渲染时无法访问window等浏览器API,这类逻辑需放在useEffect中
  React.useEffect(() => {
    console.log('客户端hydrate完成,应用可交互');
  }, []);

  return (
    <div>
      <h1>React SSR 实战示例</h1>
      <p>这是服务端渲染的内容,搜索引擎可直接抓取</p>
      <p>当前路径:{window.location.pathname}</p>
    </div>
  );
}

export default App;

五、hydrateRoot未生效的常见修复方案

  • DOM结构完全匹配:服务端renderToString生成的HTML,必须和客户端hydrateRoot挂载的组件输出完全一致,不能有额外的节点、属性差异
  • 静态资源路径正确:确保express.static托管的目录是客户端打包后的输出目录(如dist),客户端脚本的src路径需对应打包后的文件名
  • 避免服务端环境差异:组件中若需访问浏览器API(如window、document),必须放在useEffect或其他客户端生命周期钩子中,服务端渲染时不会执行这些逻辑
  • 打包配置正确:以Vite为例,创建vite.config.js指定客户端打包入口:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';

export default defineConfig({
  plugins: [react()],
  build: {
    outDir: 'dist',
    rollupOptions: {
      input: './src/client.jsx',
      output: {
        entryFileNames: 'client.js'
      }
    }
  }
});

六、运行与验证

  1. 打包客户端代码:npx vite build
  2. 启动服务端:node server.js
  3. 访问http://localhost:3000,查看页面源代码,确认<div id="root">内已有渲染好的内容(而非空节点),说明服务端渲染生效;打开控制台无hydrate相关报错,说明hydrateRoot正常工作

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 21:12:42