⚠️ This library was written to support API routes using the Next.js App Router. It was not written with the Page Router in mind.
The Next.js App router was introduced in Next.js 14, providing a new way to structure your Next.js applications. Unfortunately, their standard middleware is limited because
- The code executed in the middleware file is run in a special environment built for edge-functions. This limits the kinds of node modules you can use, such as preventing you from using standard redis clients.
- It is difficult to split up multiple middleware into separate files using their standard interface
This library provides a robust middleware solution that lets you easily integrate middleware into your API routes. Some features include:
- The ability to centralize the registration of middleware
- Exclude middleware on your routes
- Integrates well with app router API routes
- Provides a fluent API for interacting with the library
Creating your middleware is a simple three-step process. You just create a middleware file containing the middleware you'd like to register, export the corresponding RouteBuilder
that includes your middleware, import it in your routes.ts
files, and build your routes with the RouteBuilder
. We provide an example below illustrating how to use its fluent interface with your API routes.
npm i @qacomet/next-api-middleware
// Located in app/middleware/index.ts
import {
RouteMiddleware,
type Middleware,
type MiddlewareNextFunction,
} from "@qacomet/next-api-middleware";
const CaptureErrorsMiddleware: Middleware = async (
req: NextRequest,
res: NextResponse,
next: MiddlewareNextFunction
) => {
try {
// Catch any errors that are thrown in remaining
// middleware and the API route handler
return await next();
} catch (err) {
const eventId = Sentry.captureException(err);
return NextResponse.json({ error: err }, { status: 500 });
}
};
const AddRequestIdMiddleware: Middleware = async (
req: NextRequest,
res: NextResponse,
next: MiddlewareNextFunction
) => {
// Let remaining middleware and API route execute
const response = await next();
// Apply header
response.headers.set("X-Response-ID", nanoid());
return response;
};
export const middleware = RouteMiddleware.from(
CaptureErrorsMiddleware,
AddRequestIdMiddleware
);
// create API route
import { middleware } from "@/app/middleware";
const getHandler = async function (request: NextRequest) {
return NextResponse.json({ message: "hello!" });
};
// create the exports from the middleware
export const { GET } = middleware
.routes({ GET: getHandler })
.exclude("AddRequestIdMiddleware")
.build();
For further reading, check out the docs/
folder.