Routing Middleware
Routing Middleware is available on all plans
Routing Middleware executes code before a request is processed on a site, and are built on top of fluid compute. Based on the request, you can modify the response.
Because it runs globally before the cache, Routing Middleware is an effective way of providing personalization to statically generated content. Depending on the incoming request, you can execute custom logic, rewrite, redirect, add headers and more, before returning a response.
Routing Middleware runs on the Node.js runtime. See runtime options for information on how to change the runtime of your Routing Middleware.
If your routing logic doesn't need custom code, use static configuration instead of Routing Middleware. Static rules run directly on the CDN without invoking your code on every request, so they're faster and use fewer resources.
You can express these common tasks with static configuration in vercel.json or project routing rules:
| Task | Static configuration |
|---|---|
| Redirect paths | Redirects |
| Rewrite to another path or an external origin | Rewrites |
| Add response headers | headers |
| Add, change, or remove request headers sent to your app | Route transforms |
| Route based on a header, cookie, query parameter, or host | has and missing conditions |
Use Routing Middleware when the decision depends on logic that static rules can't express, such as verifying a session token, calling an API, or assigning visitors to an A/B test.
You can use Routing Middleware with any framework. To add a Routing Middleware to your app, point the proxy property in vercel.json at your entrypoint:
{
"$schema": "https://openapi.vercel.sh/vercel.json",
"proxy": {
"entrypoint": "proxy.ts"
}
}Your entrypoint exports the handler as a default export:
import { next } from '@vercel/functions';
export default function proxy(request: Request) {
const url = new URL(request.url);
// Redirect old paths
if (url.pathname === '/old-page') {
return new Response(null, {
status: 302,
headers: { Location: '/new-page' },
});
}
// Continue to the next handler
return next();
}import { next } from '@vercel/functions';
export default function proxy(request) {
const url = new URL(request.url);
// Redirect old paths
if (url.pathname === '/old-page') {
return new Response(null, {
status: 302,
headers: { Location: '/new-page' },
});
}
// Continue to the next handler
return next();
}The entrypoint can live in a subdirectory, such as src/proxy.ts. Add proxy.matcher to limit which paths run your Routing Middleware.
You can also create a middleware.ts file at your project's root directory and skip vercel.json:
export default function middleware(request: Request) {
return new Response('Hello from your Middleware!');
}
export const config = {
runtime: 'nodejs',
};export default function middleware(request) {
return new Response('Hello from your Middleware!');
}
export const config = {
runtime: 'nodejs',
};Routing Middleware has full support for the console API, including time, debug, timeEnd. Logs will appear inside your Vercel project by clicking View Functions Logs next to the deployment.
If your Routing Middleware depends on a database far away from one of our supported regions, the overall latency of API requests could be slower than expected, due to network latency while connecting to the database from a distant region. To avoid this issue, use a global database. Vercel has multiple global storage products, including Global Config and Vercel Blob. You can also explore the storage category of the Vercel Marketplace to learn which option is best for you.
The following limits apply to requests processed by Routing Middleware:
| Name | Limit |
|---|---|
| Maximum URL length | 14 KB |
| Maximum request body length | 4 MB |
| Maximum number of request headers | 64 |
| Maximum request headers length | 16 KB |
Routing Middleware is available on the Node.js and Bun runtimes. An entrypoint set through the proxy property runs on Node.js.
With the middleware.ts file convention, the default runtime is Node.js. You can set the runtime explicitly by exporting a config object with a runtime property in your middleware.ts file.
To use the Bun runtime, set bunVersion in your vercel.json file and your runtime config to nodejs.
export const config = {
runtime: 'nodejs',
};
export default function middleware(request: Request) {
// Your middleware logic here
return new Response('Hello from your Middleware!');
}export const config = {
runtime: 'nodejs'
}
export default function middleware(request) {
// Your middleware logic here
return new Response('Hello from your Middleware!');
}Routing Middleware is priced using the fluid compute model, which means you are charged by the amount of compute resources used by your Routing Middleware. See the fluid compute pricing documentation for more information.
The Vercel Observability dashboard provides visibility into your routing middleware usage, including invocation counts and performance metrics. You can get more insights with Observability Plus:
- Analyze invocations by request path
- Break down actions by type, such as redirects or rewrites
- View rewrite targets and frequency
- Use the query builder for custom insights
Learn more about Routing Middleware by exploring the following resources:
Was this helpful?