# Middleware

> Intercept request, response and errors using H3 middleware.

<important>

We recommend using composable utilities whenever possible. Global middleware can complicate application logic, making it less predictable and harder to understand.

</important>

Global middleware run on each request before route handler and act as wrappers to intercept request, response and errors.

<read-more title="Request Lifecycle" to="/guide/basics/lifecycle#\_3-dispatch-request">



</read-more>

You can register global middleware to [app instance](/guide/api/h3) using the [`H3.use`](/guide/api/h3#h3use).

**Example:** Register a global middleware that logs every request.

```js
app.use((event) => {
  console.log(event);
});
```

**Example:** Register a global middleware that matches certain requests.

```js
app.use(
  "/blog/**",
  (event, next) => {
    console.log("[alert] POST request on /blog paths!");
  },
  {
    method: "POST",
    // match: (event) => event.req.method === "POST",
  },
);
```

You can register middleware with `next` argument to intercept return values of next middleware and handler.

```js
app.use(async (event, next) => {
  const rawBody = await next();
  // [intercept response]
  return rawBody;
});
```

Example below, always responds with `Middleware 1`.

```js
app
  .use(() => "Middleware 1")
  .use(() => "Middleware 2")
  .get("/", "Hello");
```

<important>

If middleware returns a value other than `undefined` or the result of `next()`, it immediately intercepts request handling and sends a response.

</important>

When adding routes, you can register middleware that only run with them.

```js
import { basicAuth } from "h3";

app.get(
  "/secret",
  (event) => {
    /* ... */
  },
  {
    middleware: [basicAuth({ password: "test" })],
  },
);
```

For convenience, H3 provides middleware factory functions `onRequest`, `onResponse`, and `onError`:

```js
import { onRequest, onResponse, onError } from "h3";

app.use(
  onRequest((event) => {
    console.log(`[${event.req.method}] ${event.url.pathname}`);
  }),
);

app.use(
  onResponse((response, event) => {
    console.log(`[${event.req.method}] ${event.url.pathname} ~>`, response.status);
  }),
);

app.use(
  onError((error, event) => {
    console.log(`[${event.req.method}] ${event.url.pathname} !! ${error.message}`);
  }),
);
```
