Using Middleware with Next.js
Why Middleware?
Next.js API routes are thin and fast out-of-the-box, but they sometimes lack features that we need in production. Middleware can act as a layer between a request and the route file to further extend its functionality.
Common use cases
- Authentication
- Enabling CORS
- Security Checkpoints
- Request Validation
- and many more
How it works
Middleware is just a function that wraps another function by passing through the req
and res
.
Inside middleware, you can extend the functionality of your request before it runs the code inside your route file.
Example
In this example, the Middleware
function is exported from lib/middleware.js
. This simple example is
setup to apply security headers using the micro-helmet
which simply wraps the helmet
security NPM library.
Learn more about helmet here.
// lib/middleware.js
import helmet from "micro-helmet";
export default Middleware (handler) => async (req, res) => {
try {
// apply a blanket of security headers
await helmet.addHeaders(req, res);
// other custom code here
// pass this onto the next route
return handler(req, res);
}
catch (ex) {
res.status(400).json({ error: "Something went boom" })
}
}
Instead of exporting default async function (req, res) => {}
, we wrap Middleware
around the route.
The API route file would look something like this:
// pages/api/posts.js
export default Middleware(async (req, res) => {
// this route will have all the middleware methods applied
// in this example, security headers
res.json()
})
Things to remember
- Keep middleware lightweight and fast.
- Middleware can wrap other middleware. In some cases, it may be helpful to create a Database middleware and a separate Authentication middleware.