new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Nuxt · API · all subjects

server

31 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Server directory structure and automatic scanning

Nuxt automatically scans files inside the server/ directory to register API and server handlers with Hot Module Replacement (HMR) support. The server/ directory contains subdirectories: api/ (automatically prefixed with /api in routes), routes/ (for routes without /api prefix), middleware/ (for server middleware), plugins/ (for Nitro plugins), utils/ (for server utility helpers), and types/ (for server-only types).

Server handler definition requirement

Each file in the server/ directory should export a default function defined with defineEventHandler() or eventHandler() (which is an alias). The handler can directly return JSON data, a Promise, or a Response object.

Server Routes - /api prefix

Files inside ~~/server/api are automatically prefixed with /api in their route. For example, a file server/api/hello.ts becomes accessible at /api/hello.

Server Routes - routes directory without prefix

To add server routes without /api prefix, put them into ~~/server/routes directory. For example, server/routes/hello.ts becomes accessible at /hello.

Server middleware purpose and behavior

Nuxt automatically reads any file in ~~/server/middleware to create server middleware. Middleware handlers run on every request before any other server route to add or check headers, log requests, or extend the event's request object. Middleware handlers should not return anything, nor close or respond to the request, and should only inspect or extend the request context or throw an error.

Server middleware example - logging

A server middleware can log requests using getRequestURL(event): export default defineEventHandler((event) => { console.log('New request: ' + getRequestURL(event)) })

Server middleware example - extending context

A server middleware can extend the event context: export default defineEventHandler((event) => { event.context.auth = { user: 123 } })

Server plugins registration

Nuxt automatically reads any files in ~~/ server/plugins directory and registers them as Nitro plugins. This allows extending Nitro's runtime behavior and hooking into lifecycle events. Plugins should use definePlugin from 'nitro'.

Server utilities directory

Server routes are powered by h3 which comes with helper functions. You can add more helpers yourself inside the ~~/server/utils directory. Custom handler utilities can wrap the original handler and perform additional operations before returning the final response.

Server alias #server

The #server alias can be used to import files from anywhere within the server/ directory, regardless of the importing file's location. For example: import { formatUser } from '#server/utils/formatUser'. This alias ensures consistent imports across server code. The #server alias can only be used within the server/ directory; importing from #server in client code will result in an error.

Server types auto-import

Types placed in ~~/ server/types/ are auto-imported in the server context only and can be referenced in server routes, middleware, plugins, and utilities without importing them. Only files directly in server/types/ are scanned; files in nested subdirectories are not auto-imported. Types that are also needed in the Vue app belong in shared/types/ instead.

Dynamic route parameters in server routes

Server routes can use dynamic parameters within brackets in the file name like /api/hello/[name].ts and be accessed via getRouterParam(event, 'name'). For example, a request to /api/hello/nuxt would pass 'nuxt' as the name parameter.

HTTP method matching in server routes

Handle filenames can be suffixed with .get, .post, .put, .delete, etc. to match the request's HTTP method. For example, server/api/test.get.ts handles GET requests and server/api/test.post.ts handles POST requests to the same /api/test endpoint. Any other method returns a 405 error. You can also use index.[method].ts inside a directory for structuring code differently.

Catch-all routes in server

Catch-all routes are created with [...].ts or [...slug].ts in the file name. For example, ~~/server/api/foo/[...].ts registers a catch-all route for all requests that do not match any route handler, such as /api/foo/bar/baz. Access the route path via event.context.path and the route segment via event.context.params._ or event.context.params.slug if named.

Reading request body in server routes

To read the request body in a server route, use readBody(event): export default defineEventHandler(async (event) => { const body = await readBody(event); return { body } }). This should only be used in routes that accept body data (typically POST/PUT methods). Using readBody in a GET request will throw a 405 Method Not Allowed HTTP error.

Query parameters in server routes

To access query parameters in server routes, use getQuery(event): export default defineEventHandler((event) => { const query = getQuery(event); return { a: query.foo, b: query.baz } }). For a query like /api/query?foo=bar&baz=qux, this returns { a: 'bar', b: 'qux' }.

Error handling in server routes

If no errors are thrown, a status code of 200 OK is returned. Any uncaught errors return a 500 Internal Server Error. To return other error codes, throw an exception with createError({ status: 400, statusText: 'message' }). Example: if (!Number.isInteger(id)) { throw createError({ status: 400, statusText: 'ID should be an integer' }) }

Setting response status codes in server routes

To return other status codes besides 200 or 500, use the setResponseStatus utility: setResponseStatus(event, 202). For example, to return 202 Accepted in a server route.

Using useRuntimeConfig in server routes

useRuntimeConfig() can be called in server routes to access runtime configuration. Example: const config = useRuntimeConfig(); then use config.githubToken or other configured values.

Reading request cookies in server routes

To read cookies from the request in server routes, use parseCookies(event): export default defineEventHandler((event) => { const cookies = parseCookies(event); return { cookies } })

Forwarding context and headers in server routes

By default, neither the headers from the incoming request nor the request context are forwarded when making fetch requests in server routes. Use event.$fetch to forward the request context and headers: return event.$fetch('/api/forwarded'). Headers that are not meant to be forwarded (transfer-encoding, connection, keep-alive, upgrade, expect, host, accept) will not be included.

Awaiting promises after response in server routes

Use event.waitUntil to await a promise in the background without delaying the response to the client. This is useful for asynchronous tasks that shouldn't block the response, such as caching and logging. event.waitUntil(timeConsumingBackgroundTask()); return 'done' will immediately send the response while the background task completes.

Nitro configuration in nuxt.config

Use the nitro key in nuxt.config.ts to directly set Nitro configuration. This is an advanced option and custom config can affect production deployments. Example: export default defineNuxtConfig({ nitro: {} })

Nested router in server routes

Create nested routers using h3: import { createRouter, defineEventHandler, useBase } from 'h3'. Create a router instance, define routes on it, and export with useBase('/api/hello', router.handler).

Sending streams from server routes

To send file streams from server routes, use sendStream: import { sendStream } from 'h3'; export default defineEventHandler((event) => { return sendStream(event, fs.createReadStream('/path/to/file')) }). This is an experimental feature available in all environments.

Sending redirects from server routes

To send a redirect response from server routes, use sendRedirect: export default defineEventHandler(async (event) => { await sendRedirect(event, '/path/redirect/to', 302) })

Legacy handler or middleware support

Legacy Node.js-style handlers and middleware can be used with fromNodeMiddleware from h3. For handlers: export default fromNodeMiddleware((req, res) => { res.end('Legacy handler') }). For middleware: export default fromNodeMiddleware((req, res, next) => { console.log('Legacy middleware'); next() }). Never combine next() callback with an async legacy middleware or one that returns a Promise.

Server storage configuration with Redis

Configure storage mount points using nitro.storage in nuxt.config.ts. Example Redis configuration: nitro: { storage: { redis: { driver: 'redis', port: 6379, host: '127.0.0.1', username: '', password: '', db: 0, tls: {} } } }

Using server storage in API handlers

Access configured storage in API handlers using useStorage: const keys = await useStorage('redis').getKeys(); await useStorage('redis').setItem('foo', 'bar'); await useStorage('redis').removeItem('foo');

Server storage configuration via plugin

Configure storage dynamically using a server plugin: import { definePlugin } from 'nitro'; import redisDriver from 'unstorage/drivers/redis'; export default definePlugin(() => { const storage = useStorage(); const driver = redisDriver({ base: 'redis', host: useRuntimeConfig().redis.host, port: useRuntimeConfig().redis.port }); storage.mount('redis', driver) })

Cannot mix Vue and Nitro code

Do not import Vue app code (components, composables, or other app-only utilities) in server routes or utilities, and do not import server-only code in your app. Server code and client code must remain separated.

Give your agent this brain