
Security News
Axios Supply Chain Attack Reaches OpenAI macOS Signing Pipeline, Forces Certificate Rotation
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.
nextjs-proxy
Advanced tools
Universal, secure proxy for Next.js. Centralize, audit, and control all external API calls from a single entry point.
Universal, secure proxy for Next.js. Centralize, audit, and control all external API calls from a single entry point, with support for:
baseUrlIdeal for projects with multiple external integrations or governance requirements over outbound traffic.
NextJs Proxy is designed to work seamlessly with the modern, native architecture of Next.js. For optimal performance, security, and maintainability, we recommend combining:
next.config.js for declarative route mapping// next.config.js
module.exports = {
async rewrites() {
return [
{
source: "/api/proxy/:path*",
destination: "/api/proxy", // All requests go to your handler
},
];
},
};
Important: If your Next.js project uses the Pages Router (i.e., you have a
pages/folder), the middleware file must be located atsrc/middleware.tsfor Next.js to detect it correctly. If you use only the App Router, it can be in the project root or insrc/.
// src/middleware.ts
import { NextResponse, NextRequest } from "next/server";
export function middleware(request: NextRequest) {
// Example: global authentication
const token = request.headers.get("authorization");
if (!token) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}
// Add logging, rate limiting, etc. here
return NextResponse.next();
}
// Apply only to proxy routes
export const config = {
matcher: ["/api/proxy/:path*"],
};
// app/api/proxy/route.ts
import { nextProxyHandler, nextProxyHandlerAsync } from "nextjs-proxy";
// Versión síncrona (recomendada para la mayoría de casos)
export const POST = nextProxyHandler({
// ...todas tus opciones avanzadas (logging, transform, masking, etc.)
});
// Versión asíncrona (si necesitas inicialización async)
const handlerPromise = nextProxyHandlerAsync({
/* opciones */
});
export async function POST(req) {
const handler = await handlerPromise;
return handler(req);
}
With this approach you get:
This pattern is fully aligned with the best practices recommended by the Next.js team and the evolution of the framework.
⚠️ Warning: (No Turbopack Compatibility) NextJs Proxy is fully compatible with Next.js using Webpack. However, Turbopack (the new experimental bundler for Next.js) currently has limitations with local packages, workspaces, and some advanced module resolution patterns. If you experience issues using this package with Turbopack, consider the following options:
next.config.js:
experimental: {
turbo: false;
}
Turbopack is under active development and will improve over time. For the latest status, see Vercel Turbopack GitHub.
pnpm add nextjs-proxy
# or
npm install nextjs-proxy
// app/api/proxy/route.ts
import { nextProxyHandler } from "nextjs-proxy";
export const POST = nextProxyHandler({
baseUrl: process.env.EXTERNAL_API_BASE,
allowOrigins: ["http://localhost:3000"],
});
// pages/api/proxy.ts
import type { NextApiRequest, NextApiResponse } from "next";
import { nextProxyHandler } from "nextjs-proxy";
const handler = nextProxyHandler({ baseUrl: process.env.EXTERNAL_API_BASE });
export default async function proxy(req: NextApiRequest, res: NextApiResponse) {
// Minimal adapter
// You may need to create a Request from NextApiRequest if needed
// App Router is recommended for full compatibility.
res.status(405).json({ error: "Use App Router for this package" });
}
You can use nextjs-proxy in an App Router API route and call it from a Pages Router frontend. This is a common and fully supported scenario in Next.js projects.
API route (App Router):
// src/app/api/proxy/route.ts
import { nextProxyHandler } from "nextjs-proxy";
export const POST = nextProxyHandler({
baseUrl: "https://your-external-backend.com", // your external backend base URL
allowOrigins: ["http://localhost:3000"], // adjust as needed
// You can add more options: log, validate, rateLimit, etc.
});
Advanced Example
export const POST = nextProxyHandler({
baseUrl: "https://api.my-service.com",
allowOrigins: ["http://localhost:3000", "https://app.my-domain.com"],
inMemoryRate: { windowMs: 60_000, max: 100 },
log: (e) => console.log("[proxy]", e),
validate: (req) => {
const auth = req.headers.get("authorization");
return !!(auth && auth.includes("Bearer "));
},
transformRequest: ({ method, endpoint, data }) => ({
method: method ?? "GET",
endpoint: endpoint.startsWith("/internal")
? endpoint.replace("/internal", "/v2")
: endpoint,
data,
}),
transformResponse: (res) => ({ ...res, proxiedAt: new Date().toISOString() }),
maskSensitiveData: (data) => {
if (!data) return data;
if (typeof data === "object" && data !== null && "password" in data) {
return { ...data, password: "***" };
}
return data;
},
});
In a React component (e.g. src/pages/index.tsx), you should use a hook like useEffect to make the request after the component mounts:
import { useEffect } from "react";
export default function Home() {
useEffect(() => {
const fetchData = async () => {
const req = await fetch("/api/proxy", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
method: "GET",
endpoint: "/v1/health", // relative endpoint, will be resolved with baseUrl
}),
});
const res = await req.json();
};
fetchData();
}, []);
return (
<div>
<h1>Home page</h1>
</div>
);
}
This pattern allows you to keep your API logic in the App Router (recommended for new Next.js projects) while using the classic Pages Router for your frontend. Both approaches work together seamlessly.
| Option | Type | Description |
|---|---|---|
log | (info) => void | Receives events: request, response, error. |
validate | (req) => boolean | Promise | Allows to block flow (auth, permissions). |
transformRequest | ({method,endpoint,data}) => {...} | Modifies payload before fetch. |
transformResponse | (res) => any | Adjusts the response before sending to client. |
rateLimit | (req) => boolean | Promise | Custom external rate limiting. |
inMemoryRate | { windowMs, max, key? } | Simple in-memory rate limiting. |
allowOrigins | string[] | CORS whitelist. |
onCorsDenied | (origin) => any | Custom response for denied CORS. |
maskSensitiveData | (data) => any | Sanitizes data before sending. |
baseUrl | string | Prefix for relative endpoints. |
Automatically responds to OPTIONS with headers configured according to allowOrigins.
Minimal configuration:
inMemoryRate: { windowMs: 15_000, max: 20 }
Grouping is by IP (req.ip) or you can define key: (req) => 'user:'+id.
| Message | Cause | Solution |
|---|---|---|
Relative endpoint without baseUrl | Used relative endpoint without baseUrl | Define baseUrl in options |
Origin not allowed | CORS blocked | Add origin to allowOrigins |
Rate limit exceeded | Limit reached | Increase max or window |
Next.js offers several ways to proxy API requests. Here’s when to use each approach:
| Solution | Use Case | Limitations |
|---|---|---|
| Rewrites (next.config.js) | Simple path forwarding, development, no logic needed | Cannot modify headers, no auth, no logging |
| http-proxy / middleware | Custom API routes, can modify requests, more control | More boilerplate, not native to App Router |
| next-http-proxy-middleware | Simplifies http-proxy usage in API routes | Still requires custom route, less flexible |
| @navikt/next-api-proxy | Advanced token exchange, enterprise security | Complex setup, focused on auth scenarios |
| nextjs-proxy (this package) | Centralized, configurable, minimal, works with App Router | Not for legacy custom servers |
If you only need simple path forwarding for development, rewrites are enough. For production, security, and advanced logic, use nextjs-proxy.
FAQs
Universal, secure proxy for Next.js. Centralize, audit, and control all external API calls from a single entry point.
The npm package nextjs-proxy receives a total of 35 weekly downloads. As such, nextjs-proxy popularity was classified as not popular.
We found that nextjs-proxy demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
OpenAI rotated macOS signing certificates after a malicious Axios package reached its CI pipeline in a broader software supply chain attack.

Security News
Open source is under attack because of how much value it creates. It has been the foundation of every major software innovation for the last three decades. This is not the time to walk away from it.

Security News
Socket CEO Feross Aboukhadijeh breaks down how North Korea hijacked Axios and what it means for the future of software supply chain security.