# Deploy Nuxt on Lizard

Run Nuxt on Lizard with Nitro's `node-server` preset. The build produces `.output/server/index.mjs`, and a Node.js process serves pages and server routes on port `3000`. For a generated site on port `80`, use the static recipe below.

## Configure the production build

Use the current Lizard CLI from [Prepare the project](https://lizard.build/docs/framework-guides#prepare-the-project). Version 0.3.95 excludes macOS archive metadata during uploads. If an older CLI reports a `._*.ts` route error, update the CLI and upload again.

Set the preset in `nuxt.config.ts`:

```ts
export default defineNuxtConfig({
  nitro: { preset: 'node-server' },
});
```

Merge these scripts into `package.json`, keeping any other scripts your app needs:

```json
{
  "scripts": {
    "dev": "nuxt dev",
    "build": "nuxt build",
    "start": "HOST=0.0.0.0 PORT=3000 node .output/server/index.mjs"
  }
}
```

The start script uses the Linux shell in the deployment container. lizardpack detects the `nuxt` dependency and runs the build and start scripts. A fresh Nuxt project may not include `start`; add it rather than assuming `nuxt dev` will serve the production build.

| Setting | Value |
|---|---|
| Build | `npm run build` |
| Server entry | `.output/server/index.mjs` |
| Start | `npm run start` |
| Service port | `3000` |

## Test the built app

```bash
npm ci
npm run build
npm run start
```

Open `http://localhost:3000`, request an inner page directly, and call one of your `server/api` routes if present. Check that the build reports the Node server preset. A provider-specific Nitro preset can produce a different entry point.

## Deploy

After [CLI setup](https://lizard.build/docs/framework-guides#prepare-the-project), run from the Nuxt app directory:

```bash
lizard init --name nuxt-app
lizard add --service web
lizard up --service web --port 3000
lizard logs --build --service web --json
lizard logs --service web --json
lizard ps --json
```

Keep `.nuxt/`, `.output/`, `node_modules/`, and `.env` files out of the upload. Include source, config, and the lockfile. Existing service build/start overrides bypass the detection used here; see [build decision order](https://lizard.build/docs/concepts/build-pipeline#build-decision-order).

## Runtime configuration

Declare runtime settings in `runtimeConfig` and configure their matching `NUXT_*` values for the service. Keep secrets outside `runtimeConfig.public`; the public part reaches the browser. Values used to prerender pages still affect the generated build, so check both request-time and prerendered routes after a change.

Use [variables and secrets](https://lizard.build/docs/variables) to configure the service and [storage and recovery](https://lizard.build/docs/platform/storage-and-recovery) for durable data. Do not treat a local cache or session file as shared storage across replicas.

## Troubleshooting

If the process reports a missing `.output/server/index.mjs`, inspect the preset and the build output. If it reports a missing start script, add the one above. If the site never becomes healthy, check the host and port.

For a purely generated Nuxt site, serve `.output/public/` with a static Dockerfile and correct route handling. Do not start that output with the Node command above. The [Nuxt deployment guide](https://nuxt.com/docs/4.x/getting-started/deployment) explains the Node and generated outputs; [static routes and 404s](https://lizard.build/docs/framework-guides/static-routing) covers the Lizard static server setup.

## Generate a static site

For generated HTML, replace the Node preset with explicit prerender settings and change the build script to `nuxt generate`:

```ts
export default defineNuxtConfig({
  nitro: {
    prerender: { crawlLinks: true, routes: ['/'] },
  },
});
```

Add unlinked or dynamic routes to `routes` when the crawler cannot discover them. Run `npm run build` and check that `.output/public/index.html` and your inner route files exist. In the test with Nuxt 4.5.2, keeping `preset: 'node-server'` while switching only to `nuxt generate` produced the fallback pages without the site's routes. A successful build alone did not establish that the export contained the site.

Use the Dockerfile and nginx configuration in [static routes and 404s](https://lizard.build/docs/framework-guides/static-routing), with build script `build`, output directory `.output/public`, and service port `80`. The static container does not run Nuxt server routes or read runtime config for already generated pages.

See [tested versions and cloud results](https://lizard.build/docs/framework-guides/validation) for the September 9, 2026 deployment checks and their limits.
