Server Routes

Building API Routes in Nuxt

Nuxt provides a powerful server engine called Nitro that allows you to build full-stack applications. You can create API endpoints directly in your Nuxt application without needing a separate backend server.

The /server/api/ Structure

API routes are defined in the server/api/ directory. Each file becomes an API endpoint:

server/
└── api/
    ├── hello.ts          → /api/hello
    ├── users.ts          → /api/users
    └── posts/
        ├── index.ts      → /api/posts
        └── [id].ts       → /api/posts/:id

Basic API Route

Create an API route by defining an event handler:

// server/api/hello.ts
export default defineEventHandler((event) => {
  return {
    message: 'Hello from the API!'
  }
})

HTTP Methods

Handle different HTTP methods using helper functions:

export default defineEventHandler(async (event) => {
  const method = event.method

  if (method === 'GET') {
    return { data: [] }
  }

  if (method === 'POST') {
    const body = await readBody(event)
    return { created: body }
  }
})

Or use method-specific files:

server/api/todos.get.ts   → GET /api/todos
server/api/todos.post.ts  → POST /api/todos

Route Parameters

Access route parameters using getRouterParam():

// server/api/posts/[id].ts
export default defineEventHandler((event) => {
  const id = getRouterParam(event, 'id')
  return { id, title: `Post ${id}` }
})

Request Body

Read the request body with readBody():

export default defineEventHandler(async (event) => {
  const body = await readBody(event)
  // Process body data
  return { received: body }
})

Challenge

Create a simple REST API for a todo list:

  1. In server/api/todos.ts, create an endpoint that:
    • Handles GET requests: returns an array of todos
    • Handles POST requests: reads the request body and adds a new todo
    • Use an in-memory array to store todos (this resets on server restart)
  2. In pages/index.vue:
    • Fetch todos using useFetch('/api/todos')
    • Display the list of todos
    • Create a form to add new todos (use $fetch to POST)
    • Refresh the list after adding a todo

Todo structure:

{
  id: number,
  title: string,
  completed: boolean
}

Pitfall: Avoid using client-side only code (like window, document) in server routes. They run on the server, not in the browser.

Tip: Use proper error handling with createError() for better error responses.

If you get stuck, you can check the solution by clicking the button below.


Server routes are perfect for building APIs, handling form submissions, integrating with databases, and proxying external APIs. They run on the server in production, providing security for sensitive operations.

Error Handling
As Nuxt is a full-stack framework, various errors are expected to occur on both the client-side and server-side.
Plugins
Files
Editor
Initializing WebContainer
Mounting files
Installing dependencies
Starting Nuxt server
Waiting for Nuxt to ready
Terminal