Back to Blog
Tutorial8 min read2026-07-17

How to Deploy a Vike (vite-plugin-ssr) App in 2026

Vike is the framework-agnostic SSR layer on top of Vite — bring your own React, Vue, or Solid. Here's how to deploy a Vike app on PandaStack in both SSR (container) and pre-rendered (static) modes.

Ajay Kumar
Ajay Kumar
Founder & DevOps, PandaStack

Vike (https://vike.dev), formerly vite-plugin-ssr, is one of the most interesting frameworks in the Vite ecosystem: it gives you server-side rendering, routing, and data fetching without locking you into a specific UI library. React, Vue, Solid — Vike doesn't care, which is exactly why people reach for it when Next/Nuxt feel too opinionated. The flip side is that Vike hands you more of the deployment story yourself. I run PandaStack; here's how to ship one, in both of Vike's modes.

Two ways to run a Vike app

Vike supports:

  1. 1SSR (server) mode — a Node server renders each request. Deploy as a container.
  2. 2Pre-rendering (SSG) mode — pages rendered to static HTML at build time. Deploy as a static site.

Pick based on your app: dynamic, per-user pages → SSR; mostly-static content → pre-render. You can even mix, but let's do each cleanly.

Option A — SSR as a container

Vike's server integration is typically an Express (or Hono) server that calls Vike's renderPage. A minimal server/index.js:

import express from 'express'
import { renderPage } from 'vike/server'

const app = express()
const isProd = process.env.NODE_ENV === 'production'

if (isProd) {
  app.use(express.static(`${process.cwd()}/dist/client`))
}

app.get('*', async (req, res) => {
  const pageContext = await renderPage({ urlOriginal: req.originalUrl })
  const { httpResponse } = pageContext
  if (!httpResponse) return res.status(404).end()
  res.status(httpResponse.statusCode)
  res.type(httpResponse.contentType)
  res.send(httpResponse.body)
})

const port = process.env.PORT || 8080
app.listen(port, () => console.log(`vike on :${port}`))

Build both client and server:

npm run build   # runs `vike build` -> dist/client and dist/server

Dockerfile:

FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:20-alpine
WORKDIR /app
ENV NODE_ENV=production
COPY package*.json ./
RUN npm ci --omit=dev
COPY --from=build /app/dist ./dist
COPY --from=build /app/server ./server
EXPOSE 8080
CMD ["node", "server/index.js"]

Deploy: push to Git → https://dashboard.pandastack.io → New App → connect repo → it builds the Dockerfile and deploys. SSL and custom domains are automatic.

Option B — Pre-rendered as a static site

If your content is mostly static, turn on pre-rendering. In +config.js (or your Vike config):

export default {
  prerender: true,
}

Then:

npm run build   # emits static HTML into dist/client/

Deploy as static:

SettingValue
Build commandnpm run build
Output directorydist/client

Or with the CLI:

npm install -g @pandastack/cli
panda login
panda deploy --type static --dir dist/client

Static Vike is fast, cheap, and CDN-friendly — the HTML is real HTML, so it indexes well.

Data fetching and environment variables

Vike's +data hooks run on the server (in SSR mode) or at build time (in pre-render mode). Server-side data hooks can safely read secrets from process.env, which on PandaStack come from the encrypted env store — attach a managed Postgres and read DATABASE_URL inside your data function:

// pages/products/+data.js
import postgres from 'postgres'
const sql = postgres(process.env.DATABASE_URL, { ssl: 'require' })
export async function data() {
  return { products: await sql`select * from products limit 20` }
}

In pre-render mode this query runs at build time (great for content that changes on deploy). In SSR mode it runs per request (great for live data). Same code, different mode — that's Vike's flexibility.

Which mode should you choose?

  • Marketing site, docs, blog: pre-render (static). Cheapest, fastest, best SEO.
  • App with per-user or real-time data: SSR (container).
  • Both: pre-render the marketing pages, SSR the app routes — Vike allows per-page control.

Honest tradeoffs

  • Vike gives you flexibility at the cost of doing more wiring than Next/Nuxt. If you want batteries-included, those frameworks (also deployable on PandaStack) ask less of you.
  • SSR containers on the free tier scale to zero and cold-start; static deploys don't have that concern at all — another reason to pre-render when you can.
  • PandaStack is newer than the big incumbents; excellent DX, smaller ecosystem.

Wrap-up

Vike runs two ways. Container for SSR, static for pre-render — and PandaStack deploys both from the same repo with Git-push, automatic SSL, and an injected DATABASE_URL.

Docs: https://docs.pandastack.io. Start free: https://dashboard.pandastack.io.

Ready to deploy?

Start free on PandaStack.

Start free on PandaStack

More in Tutorial

Browse all Tutorial articles →

See also