renderPage()
Environment: server.
The renderPage()
function enables you to embed Vike into any server.
You only need
renderPage()
if you use SSR, see Optional.
From the perspective of a server, Vike is just a middleware:
// renderPage() doesn't depend on Node.js and can be used within any JavaScript environment:
// Node.js, AWS, Cloudflare, Vercel, Deno, Bun, Lagon, ...
import { renderPage } from 'vike/server'
// Any server: Express.js, Cloudflare Worker, AWS Lambda Function, Fastify, Hono, Nitro, ...
server.addMiddleware({
method: 'GET',
route: '*', // catch-all
async handler(request) {
const pageContextInit = { urlOriginal: request.url }
const pageContext = await renderPage(pageContextInit)
// `body` is the HTML of the page with a route matching pageContextInit.urlOriginal
const { body, statusCode, headers } = pageContext.httpResponse
const response = { body, statusCode, headers }
return response
}
})
You can embed renderPage()
into any server and any deployment environment.
Alternatively, instead of using
renderPage()
, you can pre-render your pages and remove the need for a production server (and deploy to a static host instead).
Examples
- Express.js
- Express.js + TypeScript
- Cloudflare Workers
- Vercel
- Bati (make sure to select a server like Express.js, H3, ...)
Usage
// server/index.js
// In this example we use Express.js but we could use any other server framework
import express from 'express'
import { renderPage, createDevMiddleware } from 'vike/server'
const isProduction = process.env.NODE_ENV === 'production'
const root = `${__dirname}/..`
startServer()
async function startServer() {
// Create an Express.js server
const app = express()
// Dev/prod middleware
if (!isProduction) {
const { devMiddleware } = await createDevMiddleware({ root })
app.use(devMiddleware)
} else {
// In production, we need to serve our static assets ourselves.
// (In dev, Vite's middleware serves our static assets.)
app.use(express.static(`${root}/${outDir}/client`))
}
// ...
// Other middlewares (authentication, REST/GraphQL/RPC middleware, ...)
// ...
// SSR middleware.
// Note: it should always be the last middleware, because it's a catch-all
// middleware that supersedes any middleware placed after it.
app.get('*', async (req, res) => {
const pageContextInit = {
// Required: the URL of the page
urlOriginal: req.originalUrl
// Optional: the HTTP Headers
headersOriginal: req.headers,
// Optional: information about the logged-in user (when using an
// Express.js authentication middleware that defines `req.user`).
user: req.user
// ... we can provide any additional information about the request here ...
}
const pageContext = await renderPage(pageContextInit)
const { body, statusCode, headers } = pageContext.httpResponse
headers.forEach(([name, value]) => res.setHeader(name, value))
res.status(statusCode).send(body)
})
const port = 3000
app.listen(port)
console.log(`Server running at http://localhost:${port}`)
}
The pageContext.httpResponse.body
value is the HTML string returned by the
onRenderHtml()
hook with additional <script>
and <style>
tags
automatically injected by Vike.
You can control where and what Vike injects using API >
injectFilter()
.
For HTML streams use httpResponse.pipe()
instead of pageContext.httpResponse.body
, see HTML Streaming.
Optionally, you can use pageContext.httpResponse.earlyHints
for adding early hints (103 Early Hint
), see Guides > Preloading > Early hints.
The renderPage()
function doesn't depend on Node.js and you can use renderPage()
(and therefore embed Vike) anywhere:
- Any server environment (Express.js, HatTip, Deno, Fastify, Vite's development server, Node.js's HTTP server, ...)
- Any deployment provider (AWS, Cloudflare Workers, Vercel, ...)
When modifying your server, you may need to manually restart your server for your changes to take effect. See #562.
Optional
If you pre-render all your pages then you don't need to use renderPage()
, because:
- Upon development (
$ vike dev
), Vike automatically embeds itself into Vite's development server. - Upon pre-rendering (
$ vike build
/$ vike prerender
), Vike automatically renders all your pages.
But, if you use Server-Side Rendering (SSR) and you don't pre-render all your pages, then you need a production server and you need to use renderPage()
in order to embed Vike into your server. See Guides > Pre-rendering (SSG).