Registration and execution
Register app.use() before the routes it should affect. Volt captures middleware when routes are registered. A middleware receives (context, next); return next(), or await it and return the resulting Response. Return an HTTP response early to stop the chain.
Complete global and route example
index.ts
import { Volt, type MiddlewareHandler } from 'voltts';
const timing: MiddlewareHandler = async (_c, next) => {
const start = performance.now();
const response = await next();
if (response instanceof Response) {
response.headers.set('Server-Timing', `app;dur=${performance.now() - start}`);
}
return response;
};
const requireKey: MiddlewareHandler = (c, next) => {
if (c.headers.get('x-demo-key') !== 'tutorial-key') {
return c.json({ error: 'Missing demo key' }, 401);
}
return next();
};
const app = new Volt();
// Register global middleware BEFORE registering routes.
app.use(timing);
app.get('/public', () => ({ public: true }));
// Arguments: path, handler, schema, route middleware array.
app.get('/private', () => ({ private: true }), undefined, [requireKey]);
if (globalThis._importMeta_.main) app.listen(3000);
export default app;Try both branches
bash
bun run index.ts
curl -i http://localhost:3000/public
curl -i http://localhost:3000/private
curl -i http://localhost:3000/private -H 'x-demo-key: tutorial-key'Expect 200, 401, and 200. Server-Timing is added to returned responses. The key is a tutorial value, not an authentication system.
Group middleware
Use group.use() before group routes, or pass middleware as the fourth argument to an individual route. Do not mix the handler and schema argument order: the signature is (path, handler, schema?, middleware[]?). See Route Groups.