Backend in the Same Repo
server/api Routes
Files under server/api become HTTP routes powered by Nitro. Export defineEventHandler and Nuxt handles routing, parsing, and serving.
What you'll learn
- Create a server/api/hello.ts route handler
- Export defineEventHandler returning JSON data
- Hit the route from a page with useFetch or $fetch
Nuxt’s server engine (Nitro) gives you a full backend in the same project. Any file under
server/api/ becomes an HTTP endpoint.
Your First Endpoint
// server/api/hello.ts
export default defineEventHandler(() => {
return { message: 'hi from the server' }
}) Visit /api/hello in the browser or call it from a component:
<script setup lang="ts">
const { data } = await useFetch('/api/hello')
</script>
<template>{{ data?.message }}</template> Filename to URL
server/api/users.tsto/api/usersserver/api/users/[id].tsto/api/users/:idserver/api/posts/[id]/comments.tsto/api/posts/:id/comments
Use getRouterParam to read params:
// server/api/users/[id].ts
export default defineEventHandler((event) => {
const id = getRouterParam(event, 'id')
return { id, name: 'User ' + id }
}) Reading Body & Query
// server/api/users.post.ts — .post suffix limits to POST
export default defineEventHandler(async (event) => {
const body = await readBody<{ name: string }>(event)
const query = getQuery(event)
return { created: body.name, q: query }
}) Method-suffixed filenames (.get.ts, .post.ts, .delete.ts) let you split verbs across files for
the same path.