> ## Documentation Index
> Fetch the complete documentation index at: https://aerojs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Server

> Add API routes, server-side logic, and full-stack capabilities with Nitro.

Aero is static-first: `pnpm build` produces a plain `dist/` you can deploy anywhere. When you need API routes, server-side logic, or deployment adapters, opt in to [Nitro](https://nitro.build) with a single config flag. Nitro wraps your built HTML — it does not replace Aero's page compiler.

<Note>Enable Nitro only when you need it. Static sites have no server to manage or pay for.</Note>

## Enable Nitro

Set `server: true` in your config:

```ts aero.config.ts theme={"theme":"github-dark-default"}
import { defineConfig } from '@aero-js/core/config'

export default defineConfig({
	server: true,
})
```

Then add a `nitro.config.ts` at the project root:

```ts nitro.config.ts theme={"theme":"github-dark-default"}
import { defineNitroConfig } from 'nitro/config'

export default defineNitroConfig({
	runtimeConfig: {
		appName: 'My Aero App',
	},
})
```

## File conventions

Place server files under `server/`:

```plaintext theme={"theme":"github-dark-default"}
server/
├── api/           → API handlers at /api/*
├── routes/        → Additional route handlers
├── middleware/     → Nitro request-time middleware
├── plugins/       → Nitro lifecycle hooks
└── tasks/         → Runnable server tasks
```

## API handlers

Files in `server/api/` are served at `/api/...`. The filename determines the route and HTTP method:

```ts server/api/submit.post.ts theme={"theme":"github-dark-default"}
import { defineHandler, readBody } from 'nitro/h3'

export default defineHandler(async event => {
	const body = await readBody(event)
	return { ok: true, message: body.message }
})
```

Use route parameters with `[param]` in the filename:

```ts server/api/users/[id].ts theme={"theme":"github-dark-default"}
import { defineHandler, getRouterParam } from 'nitro/h3'

export default defineHandler(event => {
	const id = getRouterParam(event, 'id')
	return { id, name: `User ${id}` }
})
```

## Preview commands

| Command            | What runs                         |
| ------------------ | --------------------------------- |
| `pnpm preview`     | Static files only — no Nitro APIs |
| `pnpm preview:api` | Full Nitro server from `.output/` |

## HTMX and Alpine.js

Aero works naturally with [HTMX](https://htmx.org) and [Alpine.js](https://alpinejs.dev) for adding interactivity. Because Aero outputs plain HTML with no framework runtime, these libraries integrate without conflicts. Include them via `<script>` tags — no special configuration needed.

## When to use server vs static

| Need                              | Approach                            |
| --------------------------------- | ----------------------------------- |
| Marketing site, blog, docs        | Static only (`server: false`)       |
| Form submissions, auth, API calls | Enable Nitro (`server: true`)       |
| Database access, server caching   | Enable Nitro + configure storage/DB |
| HTMX partial responses            | Enable Nitro + server routes        |
