Next.js HTTP Proxy Middleware
next-http-proxy-middleware is a utility that enables HTTP proxying within Next.js API routes, leveraging the widely used `http-proxy` library internally. It provides a straightforward way to forward requests from a Next.js API endpoint to an external target server, handling concerns like `changeOrigin` and path rewriting. The current stable version is 1.2.8. Release cadence appears to be irregular but active, with multiple fixes and minor feature additions within the last year. A key differentiator is its direct integration as a middleware function for Next.js API routes, simplifying setup compared to manually configuring `http-proxy`. However, the library itself recommends considering Next.js's built-in `rewrites` or directly using `http-proxy` for simpler cases, suggesting this library is best suited when its specific `pathRewrite` or `onProxyInit` options are beneficial.
Common errors
-
Error: This expression is not callable.
cause Often seen in TypeScript projects when a module's default export is incorrectly typed or imported, or when an older version of TypeScript has issues with CJS/ESM interop.fixEnsure you are using `import httpProxyMiddleware from 'next-http-proxy-middleware';` and your `tsconfig.json` is correctly configured for your Next.js version (e.g., `"esModuleInterop": true`, `"moduleResolution": "node"`). Update `next-http-proxy-middleware` to the latest version to get the most recent type definitions. (Fix from v1.0.5 release notes). -
API resolved without sending a response for /api/proxy/my-path, this may result in stalled requests.
cause Next.js warns when an API route handler finishes without `res.end()` or `res.json()`. Proxy middleware handles the response, so Next.js needs to know it's being handled externally.fixAdd `export const config = { api: { externalResolver: true } };` to your API route file. This tells Next.js that an external resolver (like the proxy) will handle the response, suppressing the warning. -
Error: read ECONNRESET
cause This typically indicates that the connection to the target proxy server was unexpectedly closed by the peer. This could be due to the target server restarting, being overloaded, or having network issues.fixCheck the health and logs of your target proxy server (`target` option). Ensure the target URL is correct and accessible. Implement robust error handling in `onProxyInit` to log and potentially retry or respond gracefully to the client. -
TypeError: Cannot read properties of undefined (reading 'on')
cause This error usually occurs if the `proxy` instance passed to `onProxyInit` is `undefined` or not correctly initialized, often due to an outdated or corrupted `http-proxy` dependency, or incorrect usage of `onProxyInit`.fixVerify that `next-http-proxy-middleware` and `http-proxy` are correctly installed and up-to-date. Ensure the `onProxyInit` callback function signature matches `(proxy: httpProxy) => { ... }` as specified in the README example.
Warnings
- gotcha The library internally recommends trying Next.js's native `rewrites` feature first, as it's often sufficient for basic proxying needs and requires no external libraries. Only use `next-http-proxy-middleware` if more advanced features like `onProxyInit` or complex `pathRewrite` logic are necessary.
- gotcha When using this middleware in Next.js API routes, it is critical to disable Next.js's default `bodyParser` and enable `externalResolver` in the API route's `config`. Failure to do so can lead to `Content-Type` issues for specific requests (like `multipart/form-data`) or unexpected behavior, as Next.js's body parsing interferes with the proxy's handling.
- breaking Prior to v1.0.9/v1.0.8-hotfix.1, `http-proxy` and its types were potentially incorrectly handled or considered optional. As of these versions, `http-proxy` and its types were explicitly moved into `dependencies` to ensure correct installation and typing.
- gotcha Version 1.2.4 introduced a fix for memory leaks by ensuring a new proxy instance is created for each request. Older versions might suffer from memory accumulation under high load.
- gotcha The `pathRewrite` option handles patterns in the order they are entered in the array. Incorrect ordering can lead to unintended path rewrites, especially with overlapping or less specific patterns preceding more specific ones.
Install
-
npm install next-http-proxy-middleware -
yarn add next-http-proxy-middleware -
pnpm add next-http-proxy-middleware
Imports
- httpProxyMiddleware
const httpProxyMiddleware = require('next-http-proxy-middleware');import httpProxyMiddleware from 'next-http-proxy-middleware';
- NextHttpProxyMiddlewareOptions
import { NextHttpProxyMiddlewareOptions } from 'next-http-proxy-middleware';import type { NextHttpProxyMiddlewareOptions } from 'next-http-proxy-middleware'; - config
export const config = { api: { externalResolver: true, bodyParser: false } };
Quickstart
import type { NextApiRequest, NextApiResponse } from "next";
import httpProxyMiddleware from "next-http-proxy-middleware";
const isDevelopment = process.env.NODE_ENV !== "production";
export const config = {
api: {
// Enable `externalResolver` option in Next.js for custom response handling.
externalResolver: true,
// Disable Next.js's default bodyParser to allow the proxy to handle raw request bodies.
bodyParser: false,
},
};
export default async (req: NextApiRequest, res: NextApiResponse) => {
const targetUrl = process.env.NEXT_PUBLIC_API_PROXY_URL ?? 'http://localhost:3000'; // Fallback for local dev
return httpProxyMiddleware(req, res, {
target: targetUrl,
pathRewrite: [
{
patternStr: '^/api/proxy/(.*)$',
replaceStr: '/$1',
},
],
// Optionally handle proxy events, e.g., for logging or modifying headers
onProxyInit: (proxy) => {
proxy.on('proxyReq', (proxyReq, req, res) => {
console.log(`Proxying request: ${req.url} -> ${proxyReq.path}`);
});
proxy.on('error', (err, req, res) => {
console.error('Proxy error:', err);
if (!res.headersSent) {
res.writeHead(500, { 'Content-Type': 'text/plain' });
res.end('Proxy error occurred.');
}
});
},
});
};