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

如何为单个页面开启SSR模式?不全局启用SSR且其余页面用SPA模式

仅为单个页面启用SSR,其余页面保持SPA模式的实现方案

如果你不想全局开启SSR,只想指定某一个页面走服务端渲染,其余页面维持SPA模式,可以通过自定义serverMiddleware拦截请求,针对目标路由单独处理SSR渲染,其他路由直接返回SPA入口文件。以下是具体实现步骤:

1. 编写自定义SSR处理中间件

在项目根目录新建server/middleware/ssr-route-handler.js文件,内容如下:

const { createServer, build } = require('vite')
const vuePlugin = require('@vitejs/plugin-vue')
const fs = require('fs')
const path = require('path')

// 替换成你需要开启SSR的目标路由
const TARGET_SSR_ROUTE = '/special-ssr-page'

async function ssrRouteHandler(req, res, next) {
  // 只处理目标路由的请求
  if (req.url.startsWith(TARGET_SSR_ROUTE)) {
    // 初始化Vite SSR服务
    const vite = await createServer({
      server: { middlewareMode: 'ssr' },
      plugins: [vuePlugin()]
    })

    // 加载SSR入口模块
    const { render } = await vite.ssrLoadModule('/src/entry-server.js')
    // 读取基础HTML模板
    const template = fs.readFileSync(path.resolve(__dirname, '../../index.html'), 'utf-8')
    const transformedHtml = await vite.transformIndexHtml(req.url, template)

    // 渲染SSR页面内容
    const appHtml = await render(req.url)
    // 将渲染结果插入模板
    const finalHtml = transformedHtml.replace('<!--ssr-outlet-->', appHtml)

    res.setHeader('Content-Type', 'text/html')
    res.end(finalHtml)
    await vite.close()
  } else {
    // 其他路由直接返回SPA入口HTML
    const spaHtml = fs.readFileSync(path.resolve(__dirname, '../../index.html'), 'utf-8')
    res.setHeader('Content-Type', 'text/html')
    res.end(spaHtml)
    // 调用后续中间件(如果有的话)
    next()
  }
}

module.exports = ssrRouteHandler

2. 创建SSR入口文件

在src目录下新建entry-server.js,用于处理服务端渲染逻辑:

import { createSSRApp } from 'vue'
import App from './App.vue'
import { createRouter } from './router'

export async function render(url) {
  const app = createSSRApp(App)
  const router = createRouter()

  // 跳转到目标路由
  await router.push(url)
  await router.isReady()

  // 将Vue实例渲染为字符串
  return app.renderToString()
}

3. 注册serverMiddleware

在项目的配置文件中(比如vite.config.js)注册这个中间件:

export default {
  server: {
    middleware: [
      './server/middleware/ssr-route-handler.js'
    ]
  }
}

关键注意点

  • 目标页面的组件要兼容SSR:避免在组件初始化阶段使用window、document等浏览器专属API,可通过onMounted钩子或process.client(如果是Nuxt)判断环境后再调用。
  • 如果是Nuxt.js项目,逻辑可以简化:无需手动搭建Vite SSR,直接在中间件中调用Nuxt的内部渲染方法处理目标路由,其他路由返回nuxt.html即可。
  • 生产环境下,建议提前构建SSR相关资源,避免每次请求都重新构建,提升性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 22:10:11