Deploying SSR — Node Hosts

Vercel, Render, Fly.io, AWS — All Detected

Deploying SSR — Node Hosts

nuxi build emits a Node-compatible server by default. Nitro detects the deploy target automatically and tweaks the output to fit each platform.

4 min read Level 2/5 #nuxt#deploy#ssr
What you'll learn
  • Deploy to Vercel, Netlify, or Render with zero config
  • Use nitro.preset to force a specific target
  • Self-host with PM2 or Docker

For real SSR — where every request renders fresh HTML — you need a Node runtime. Nitro produces a server that works on every major host, and detects the target from environment variables so you usually don’t configure anything.

Zero-Config Hosts

Run nuxi build, push, deploy. Nitro auto-detects:

  • VercelVERCEL=1 → emits .vercel/output/
  • NetlifyNETLIFY=true → emits netlify/functions/server
  • Render — sets the right Procfile entry
  • AWS Amplify — detects Amplify and outputs an SSR-compatible bundle

Connect the Git repo to the platform, the build runs, the SSR server boots.

Force a Preset

To override detection — or to build locally for a specific target — set nitro.preset in nuxt.config.ts or via env var.

export default defineNuxtConfig({
  nitro: { preset: 'vercel' },
})

Or at the command line:

NITRO_PRESET=node-server nuxi build

Self-Host with Node

The default preset is node-server — a plain Node HTTP server. After nuxi build:

node .output/server/index.mjs
# Listening on http://0.0.0.0:3000

Put it behind PM2 or systemd for restarts. Front it with nginx for TLS.

npm i -g pm2
pm2 start .output/server/index.mjs --name my-app
pm2 startup && pm2 save

Dockerize

A two-stage Dockerfile keeps the final image small.

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

FROM node:22-alpine
WORKDIR /app
COPY --from=build /app/.output ./.output
ENV NODE_ENV=production HOST=0.0.0.0 PORT=3000
EXPOSE 3000
CMD ["node", ".output/server/index.mjs"]

Health Checks

Most platforms ping a URL to know the app is up. Add a tiny server route:

// server/api/_health.ts
export default defineEventHandler(() => ({ ok: true, ts: Date.now() }))
Deploying to the Edge →