Next.js Middleware Wrappers
raw JSON →nextjs-middleware-wrappers is a utility package designed to streamline the composition of middleware functions in Next.js API routes and endpoints. It provides a `wrappers` function that allows developers to chain multiple higher-order middleware functions in a more readable and type-safe manner, contrasting with deeply nested function calls. The package, currently at version 1.3.0, is actively maintained with a structured release process informed by Angular JS commit message conventions, implying regular updates for fixes, features, and potential breaking changes. Its primary differentiator lies in its ability to preserve the input and output types across multiple middleware layers, significantly reducing the common type-mismatch issues encountered when manually composing such functions. This utility aims to improve code clarity and maintainability for applications heavily relying on request-based middleware patterns within the Next.js ecosystem, ensuring that complex middleware logic remains manageable and robust.
Common errors
error Argument of type '(req: NextApiRequest, res: NextApiResponse) => Promise<void>' is not assignable to parameter of type '(next: any) => Promise<any>' ↓
wrappers (except the very last one, which is the final API handler) are higher-order functions that accept a next argument and return an async (req, res) => {...} function. For example: (next) => async (req, res) => { /* middleware logic */ return next(req, res); }. error Cannot find module 'nextjs-middleware-wrappers' or its corresponding type declarations. ↓
npm install nextjs-middleware-wrappers or yarn add nextjs-middleware-wrappers to install the package. If the error persists, check your tsconfig.json to ensure moduleResolution is set appropriately (e.g., NodeNext or Bundler) for modern module systems. error TypeError: (0, nextjs_middleware_wrappers__WEBPACK_IMPORTED_MODULE_0__.wrappers) is not a function ↓
import wrappers from 'nextjs-middleware-wrappers' to the correct named import: import { wrappers } from 'nextjs-middleware-wrappers';. Warnings
breaking The package follows a strict semantic versioning policy, where `BREAKING CHANGE:` tags in commit messages indicate changes that may require adjustments to your code. Always review release notes or commit history when upgrading major versions to understand potential breaking changes. ↓
gotcha Ensure all custom middleware functions passed to `wrappers` adhere to the expected higher-order function signature: `(next: Function) => async (req: NextApiRequest, res: NextApiResponse) => Promise<any>`. Incorrectly typed or structured middleware can lead to type errors during development or unexpected runtime behavior, especially when attempting to pass additional arguments. ↓
gotcha Middleware functions are executed in the exact order they are provided to the `wrappers` function. Be critically mindful of this sequence, as it dictates the flow of control and data transformation. Incorrect ordering can lead to logical errors, such as attempting to access data that an earlier middleware was supposed to set, or security vulnerabilities if validation occurs too late. ↓
Install
npm install nextjs-middleware-wrappers yarn add nextjs-middleware-wrappers pnpm add nextjs-middleware-wrappers Imports
- wrappers wrong
const wrappers = require('nextjs-middleware-wrappers');correctimport { wrappers } from 'nextjs-middleware-wrappers'; - wrappers (default import mistake) wrong
import wrappers from 'nextjs-middleware-wrappers';correctimport { wrappers } from 'nextjs-middleware-wrappers'; - Types (Next.js specific)
import type { NextApiRequest, NextApiResponse } from 'next';
Quickstart
import { NextApiRequest, NextApiResponse } from 'next';
import { wrappers } from 'nextjs-middleware-wrappers';
// Example middleware: Adds a timestamp to the request object
const withTimestamp = (next) => async (req: NextApiRequest, res: NextApiResponse) => {
// For demonstration, cast req to any to add custom properties
(req as any).timestamp = Date.now();
console.log('Middleware: Timestamp added:', (req as any).timestamp);
return next(req, res);
};
// Example middleware: Logs the request method and path with a configurable prefix
const withRequestLogger = (logPrefix: string) =>
(next) =>
async (req: NextApiRequest, res: NextApiResponse) => {
console.log(`${logPrefix} GOT REQUEST ${req.method} ${req.url}`);
return next(req, res);
};
// The actual Next.js API route handler function
const myApiHandler = async (req: NextApiRequest, res: NextApiResponse) => {
console.log('Handler received request at timestamp:', (req as any).timestamp);
res.status(200).json({
message: 'Hello from API!',
method: req.method,
url: req.url,
timestamp: (req as any).timestamp,
});
};
// Compose the handler with middleware using wrappers
// Middleware are applied in the order they are listed.
export default wrappers(
withTimestamp,
withRequestLogger("[API_LOG]"), // Middleware with parameters
myApiHandler
);