# Nuxt

Use nuxt generate, not nuxt build — the static output lands in .output/public/.

Nuxt has two build commands and only one of them produces a static site.

- `nuxt build` → a **server** bundle. Needs a Node runtime. Not deployable here.
- `nuxt generate` → prerendered static files in `.output/public/`.

Use `generate`.

```console title="nuxt"
$ npx nuxt generate
✔ Prerendered 18 routes
✔ Generated public .output/public
$ one9x pages release ./.output/public --site mysite --deploy
✓ v1 live
→ https://mysite.one9x.app/
```

**No `--spa`.** `generate` prerenders a real HTML file per route.

## The dot in the path is fine

Dotfiles are skipped on upload, and `.output` starts with a dot — but you point
the release at `.output/public`, so the dot is on a *parent* of the directory
being uploaded, not on anything inside it. Nothing is dropped.

If you would rather not think about it at all, set a plainer output directory:

```js
// nuxt.config.ts
export default defineNuxtConfig({
  nitro: { output: { publicDir: 'dist' } },
});
```

## Routes that were not prerendered

`generate` prerenders what it can crawl from your links. A route reachable only
by a form submit or a dynamic parameter may be missed, and the result is a 404
on a page that works in development. List them explicitly:

```js
// nuxt.config.ts
export default defineNuxtConfig({
  nitro: {
    prerender: { routes: ['/pricing', '/blog/hello-world'] },
  },
});
```

## Server routes

Anything under `server/api/` needs a running Nitro server and will not exist in
a generated site. Nuxt does not fail the build over it — the routes are simply
absent, which is worth knowing before you find out from a fetch that 404s.

## Start from a template

Live, and deployed by the workflow in that repo on every push:
**[nuxt.one9x.app](https://nuxt.one9x.app/)**.

[`one9x/template-nuxt`](https://github.com/one9x/template-nuxt) is a minimal Nuxt starter
with this deploy already wired up. Press **Use this template** on GitHub to get
your own copy, or read it as a reference for a project you already have.

Set two things in the new repo under **Settings → Secrets and variables →
Actions** and it deploys on every push:

| | Name | Value |
| --- | --- | --- |
| Variable | `ONE9X_SITE` | the site to deploy to |
| Secret | `ONE9X_TOKEN` | `one9x tokens create "github actions"` |

Until `ONE9X_SITE` is set the workflow is skipped rather than failed — a fresh
copy should not open with a red X.

## Deploying on every push

```yaml
- uses: actions/setup-node@v5
  with: { node-version: 22, cache: npm }
- run: npm ci
- run: npx nuxt generate
- uses: one9x/pages-deploy@v1
  with:
    site: mysite
    dir: .output/public
    token: ${{ secrets.ONE9X_TOKEN }}
    deploy: ${{ github.ref == 'refs/heads/main' }}
```