Migrate to RunxBuild today!! Deploy More while Spending Less

Calculate your savings
unxBuild

Nuxt Hosting: Free Deployment for SSG, SSR, and Hybrid Apps

Sean

Platform Writer

Sep 23, 2026
8 min read

Nuxt hosting is not one thing because Nuxt is not one rendering mode. Static site generation (nuxi generate) outputs plain HTML and needs nothing more than a static host or CDN. Server-side rendering runs Nitro, Nuxt’s server engine, as a persistent Node process and needs a host that keeps a process alive. Hybrid rendering, set with routeRules in nuxt.config, prerenders some routes and serves others dynamically from the same Nitro server, needing the SSR host either way. Picking the wrong host for the mode is the single most common Nuxt deployment mistake, and it shows up as a working local dev server and a broken production build.

Nuxt Hosting: Free Deployment for SSG, SSR, and Hybrid Apps

The official Nuxt docs already explain the three modes accurately, and Stack Overflow and Reddit threads are full of people who deployed SSR Nuxt to a host that only serves static files and got a blank page or a build that silently fell back to client-only rendering. What is missing from most of it is a direct mapping: given the mode you picked, what does the host actually need to run, and what does the nuxt.config and start command look like for that host. This post walks through SSG, full SSR, and hybrid routeRules in turn, with the config and the start command for each, and ends where the choice actually lands: a static host for a pure SSG build, a Node service for anything that renders on request.

Table of contents

Three rendering modes, one framework

Nuxt ships three ways to render a page, and the confusion in the wild, including a Reddit thread asking why it is so hard to deploy Nuxt SSR to the cloud, mostly comes from treating them as one thing. Static site generation, triggered by nuxi generate, renders every route to plain HTML at build time and produces a folder of files with no server logic left to run. Server-side rendering, the default when you run nuxt build and start the server, keeps Nitro, Nuxt’s server engine, running as a persistent process that renders each page on request, pulling fresh data every time. Hybrid rendering sits between the two: routeRules in nuxt.config lets you mark some routes as prerendered at build time and leave others dynamic, served by the same Nitro server, so a marketing page can be static while a dashboard route stays live.

The three modes are not upgrades of each other. They are different answers to the same question, how fresh does each page need to be, and the hosting decision follows directly from the answer.

Static (SSG): nuxi generate and a static host

Running nuxi generate (or nuxt generate on Nuxt 2) pre-renders every route Nuxt can discover, writes the output to .output/public, and produces something a static host serves without running any JavaScript on the server side. Dynamic routes need a nuxt.config hint so the generator knows which paths to crawl, but the output is still just HTML, CSS, and client-side JS once the build finishes.

export default defineNuxtConfig({
  // ssr: true is the default and is what nuxi generate pre-renders.
  // No extra config needed for a pure static build.
})
{
  "scripts": {
    "generate": "nuxi generate",
    "preview": "nuxi preview"
  }
}

Deploy the contents of .output/public to any static host and the app works exactly like it did in nuxi preview, because there is no server left in the equation. This is the cheapest and simplest option, and it is the wrong one the moment a page needs to read a database or check a session on every request, which is what the next mode is for.

Server-rendered (SSR): Nitro as a Node process

Full SSR keeps a Node process running continuously. nuxt build produces .output/server/index.mjs, and starting it with node .output/server/index.mjs launches Nitro listening on a port, rendering each request fresh, and staying alive between requests the way any Node server does. This is the mode that needs a host built for persistent processes rather than static files: something that keeps the process running, restarts it if it crashes, and routes traffic to the port it is listening on.

node .output/server/index.mjs
# Nitro listens on $PORT (default 3000) and stays running
export default defineNuxtConfig({
  nitro: {
    preset: 'node-server' // the default; explicit here for clarity
  }
})

Deploying this build to a static host produces the blank-page symptom people report: the static host serves whatever HTML happens to exist and ignores the server code entirely, because it was never designed to run one. SSR Nuxt needs a Node service, full stop, and the PORT environment variable Nitro reads has to match whatever the host expects it to listen on.

Hybrid: routeRules mixing prerendered and dynamic routes

routeRules in nuxt.config let a single Nuxt app prerender some paths at build time and render others on request, all served from the same Nitro server. A marketing homepage can be prerender: true while an authenticated dashboard stays fully dynamic, and both live in one deploy instead of two separate apps.

export default defineNuxtConfig({
  routeRules: {
    '/': { prerender: true },
    '/blog/**': { swr: 3600 },
    '/dashboard/**': { ssr: true }
  }
})

The hosting requirement for hybrid mode is the same as full SSR, a Node process has to be running, because even one dynamic route means Nitro’s server has to exist. Hybrid does not reduce the hosting requirement; it changes how much work that server does per request, which matters for cost and response time but not for whether a Node host is needed.

Picking wrong: the symptoms and the fix

Three symptoms show up repeatedly when the rendering mode and the host disagree:

  • A blank page or an empty root div on a static host serving an SSR build, because the client-side JavaScript that would normally hydrate a server-rendered page never received real markup to hydrate.
  • A 404 on every dynamic route when a hybrid app is deployed as if it were pure static output, because the static host has no server to fall back to for routes that were never prerendered.
  • Environment variables that work locally but are undefined in production, because build-time variables (available to nuxi generate) and runtime variables (available to a running Nitro server) are read at different points, and a static build has no runtime left to read from at all.

The fix in every case is the same: confirm which mode the app actually uses, then confirm the host matches it. A pure nuxi generate output belongs on a static host. Anything with SSR or a dynamic routeRules entry needs a Nitro-compatible Node process kept alive.

One more mismatch worth naming: a Node host that only exposes a fixed port, or that expects a specific start command it discovers automatically, can fail an SSR deploy even when the mode and the preset are both correct, simply because the host never ran the command that starts Nitro. Confirm the start command explicitly, node .output/server/index.mjs, rather than assuming a generic Node buildpack will find it on its own, and confirm the host reads PORT from the environment the same way Nitro writes it. A working local nuxi preview and a broken production deploy almost always trace back to one of these three mismatches, mode versus host, missing start command, or a PORT the two sides disagree on, not to a bug in Nuxt itself.

How this fits the rest of the stack

Once the rendering mode is decided, the hosting decision follows automatically rather than needing its own research project. A Nuxt app built entirely with nuxi generate is static output, HTML, JS, and CSS with no server required, and belongs on a static host with a CDN in front of it. A Nuxt app using SSR or hybrid routeRules is a persistent Node process that has to stay running, accept requests, and restart if it crashes, which is a service, not a static site. The RunxBuild hosting calculator prices both: a static site for the pure SSG build, or a Node service sized to the traffic an SSR Nitro server actually receives. Match the plan to the mode you picked, not the other way around.

Useful related references:

FAQ

Does Nuxt need a Node server to run?

Only if it uses SSR or any dynamic routeRules entry. A Nuxt app built entirely with nuxi generate produces static HTML with no server logic left, and a static host is enough. The moment one route needs to render on request rather than at build time, Nitro has to run as a persistent Node process, and the host needs to support that.

What is the difference between nuxi generate and nuxt build?

nuxi generate pre-renders every route to static files in .output/public and produces no server to run afterward. nuxt build compiles the app including the Nitro server into .output/server, meant to be started with node .output/server/index.mjs and kept running. Generate is for static hosting; build is for SSR or hybrid hosting.

Can I deploy a Nuxt SSR app to a static host?

Not successfully as SSR. A static host serves files and runs no server-side code, so an SSR build deployed there either shows a blank page or falls back to an empty client-rendered shell with none of the server-fetched data. The options are switching the app to ssr: false and pre-rendering, or deploying to a host that runs the Nitro server as a Node process.

What does the Nitro node-server preset actually produce?

It compiles the app into a single Node entry point at .output/server/index.mjs that, when run with node, starts an HTTP server listening on a configurable port, handling both rendering and any server API routes defined in the app. It is the standard preset for deploying Nuxt SSR to a generic Node host rather than a specific serverless platform.

When should I use routeRules instead of full SSR or full static?

When different parts of the same app have different freshness needs, a marketing section that rarely changes and a dashboard that always needs live data. routeRules prerenders the static parts and renders the rest dynamically from one Nitro server, avoiding both the cost of full SSR on pages that do not need it and the limitation of forcing dynamic pages into a static build.

#nuxt hosting#host nuxt app#deploy nuxtjs#free nuxt hosting#Nuxt Nitro