Lifecycle

Understand how Nitro runs and serves incoming requests to your application.
Nitro v3 Alpha docs are a work in progress — expect updates, rough edges, and occasional inaccuracies.

A request can be intercepted and terminated (with or without a response) from any of these layers, in this order:

Route rules

The matching route rule defined in the Nitro config will execute. Note that most of the route rules can alter the response without terminating it (for instance, adding a header).

nitro.config.ts
import { defineNitroConfig } from "nitro/config";

export default defineNitroConfig({
  routeRules: {
    '/**': { headers: { 'x-nitro': 'first' } }
  }
})
Read more in Routing > Route rules.

Global middleware

Any global middleware defined in the middleware/ directory will be run:

middleware/info.ts
import { defineHandler } from "nitro/h3";

export default defineHandler((event) => {
  event.context.info = { name: "Nitro" };
});
Returning from a middleware will close the request and should be avoided when possible.
Learn more about Nitro middleware.

Server entry

If defined, the server entry handler will be run:

server.ts
import { defineHandler } from "nitro/deps/h3";

export default defineHandler((event) => {
  if (event.path === "/") {
    return "Home page";
  }
});
Think of the server entry as the last global middleware to run.
Learn more about Nitro server entry.

Routes

At this stage, Nitro will look at defined routes in the routes/ folder to match the incoming request.

routes/api/hello.ts
export default (event) => ({ world: true })
Learn more about Nitro file-system routing.

Renderer

If no route is matched, Nitro will look for a renderer handler (defined or auto-detected) to handle the request.

Learn more about Nitro renderer.