如何为单个页面开启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
相关产品推荐
相关产品推荐

