Environment: Node.js.

We use renderPage() to server-side render a page:

// server.js
// Environment: Node.js server

// In this example we use Express.js but we could use any other server framework
import express from 'express'
import { renderPage } from 'vite-plugin-ssr'

const isProduction = process.env.NODE_ENV === 'production'
const root = `${__dirname}/..`


async function startServer() {
  const app = express()

  if (isProduction) {
  } else {
    const vite = await import('vite')
    viteDevMiddleware = (await vite.createServer({
      server: { middlewareMode: true }

  app.get('*', async (req, res, next) => {
    const pageContextInit = { urlOriginal: req.originalUrl }
    const pageContext = await renderPage(pageContextInit)
    if (pageContext.httpResponse === null) return next()
    const { body, statusCode, contentType } = pageContext.httpResponse

  const port = 3000
  console.log(`Server running at http://localhost:${port}`)
  • pageContext.httpResponse.statusCode is either 200, 404, or 500.
  • pageContext.httpResponse.contentType is either text/html;charset=utf-8 or application/json. (The Content-Type is application/json when Client Routing fetches the pageContext of the newly navigated page.)
  • pageContext.httpResponse.body is the HTML string returned by the render() hook with additional <script> and <style> tags automatically injected by vite-plugin-ssr.
  • pageContext.httpResponse is null if:
    • An error occurs while rendering the page and you didn't create an file.
    • An error occurs while rendering
    • The URL is skipped: vite-plugin-ssr doesn't render certain URLs. (E.g. pageContext.urlOriginal === '/favicon.ico' because browsers automatically make favicon requests).

renderPage() is framework agnostic: we can use vite-plugin-ssr with any server framework (Koa, Hapi, Fastify, vanilla Node.js, ...) and any deploy environment (AWS, Cloudflare Workers, Vercel, ...).