Deploy Nuxt.js: SSR and Static Both Covered
Nuxt.js is the Vue-powered meta-framework that adds file-based routing, server-side rendering, static site generation, and full-stack API routes to the Vue ecosystem. The deployment strategy differs depending on your rendering mode — static generation (SSG) outputs plain files; SSR requires a running Node.js server.
PandaStack supports both. Static sites are served via CDN. SSR apps run as Docker containers. This guide covers both paths.
Prerequisites
- Node.js 20+ installed locally
- Docker (for SSR only)
- A GitHub account
- PandaStack CLI:
npm install -g @pandastack/cli
Step 1 — Create a Nuxt 3 Application
npx nuxi@latest init my-nuxt-app
cd my-nuxt-app
npm install
npm run dev
# http://localhost:3000Path A — Static Site Generation (SSG)
SSG pre-renders every page at build time and outputs static HTML. This is the best choice for marketing sites, blogs, documentation, and any content that does not change per request.
Generate the Static Build
npx nuxi generateThis outputs files to .output/public/:
ls .output/public/
# _nuxt/ index.html 200.html 404.htmlConfigure pandastack.json for SSG
{
"type": "static",
"buildCommand": "npx nuxi generate",
"outputDir": ".output/public"
}The 200.html file in Nuxt's output serves as a fallback for client-side navigation — PandaStack's static hosting uses it automatically.
Deploy
git add .
git commit -m "Nuxt SSG config for PandaStack"
gh repo create my-nuxt-app --public --source=. --push
panda deploy---
Path B — Server-Side Rendering (SSR)
SSR renders pages on-demand per request. Use this for personalised content, authenticated dashboards, or pages that depend on real-time data.
Write a Dockerfile
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/.output ./.output
EXPOSE 3000
CMD ["node", ".output/server/index.mjs"]Nuxt 3's npm run build uses Nitro to produce a self-contained server bundle at .output/server/index.mjs — no separate web server required.
Build and test locally:
docker build -t my-nuxt-ssr .
docker run -p 3000:3000 my-nuxt-ssr
curl http://localhost:3000Add a Health Check Route
Create server/routes/health.get.ts:
export default defineEventHandler(() => {
return { status: 'ok' };
});Configure pandastack.json for SSR
{
"type": "container",
"healthCheckPath": "/health"
}Deploy the SSR Container
git add .
git commit -m "Nuxt SSR with Dockerfile and PandaStack config"
gh repo create my-nuxt-ssr --public --source=. --push
panda deploy---
Environment Variables for Both Modes
Nuxt supports runtime and build-time config in nuxt.config.ts:
export default defineNuxtConfig({
runtimeConfig: {
// Private — only available server-side
databaseUrl: process.env.DATABASE_URL,
// Public — exposed to the client
public: {
apiBase: process.env.NUXT_PUBLIC_API_BASE || 'https://api.my-backend.pandastack.io'
}
}
})Set DATABASE_URL and NUXT_PUBLIC_API_BASE in the PandaStack dashboard under Environment Variables.
Access them in components:
const config = useRuntimeConfig();
const apiBase = config.public.apiBase;Connect a Managed Database (SSR)
For SSR apps that need a database, provision one with PandaStack:
panda db create --type postgres --name nuxt-dbThe connection string is automatically added to your project's environment.
Verify the Deployment
curl https://my-nuxt-app.pandastack.io
panda logs --followChoosing Between SSG and SSR
Use SSG when your content changes infrequently and can be rebuilt on deploy — blog posts, documentation, marketing pages, and product catalogs. SSG pages load faster because they are served as pre-built HTML from a CDN with no server computation on each request.
Use SSR when content must be personalised per user, must reflect real-time data, or when you have thousands of dynamic routes that make full pre-rendering impractical. SSR pages are generated on demand but require a running server, which PandaStack provides via Docker container deployment.
A hybrid approach is also possible with Nuxt 3 — pre-render public pages statically while keeping authenticated routes server-rendered. Configure this per-route in nuxt.config.ts:
export default defineNuxtConfig({
routeRules: {
'/': { prerender: true },
'/blog/**': { prerender: true },
'/dashboard/**': { ssr: true }
}
})Summary
Nuxt.js gives you flexibility — pre-render for maximum speed, or SSR for dynamic content. PandaStack supports both modes: static via CDN, SSR via Docker container. Configure pandastack.json appropriately for each mode. Full docs at [docs.pandastack.io](https://docs.pandastack.io).