Getting Started with Routing Middleware
Routing Middleware lets you to run code before your pages load, giving you control over incoming requests. It runs close to your users for fast response times and are perfect for redirects, authentication, and request modification.
Routing Middleware is available on the Node.js, and Edge runtimes. Node.js is the default runtime for Routing Middleware, to configure runtimes, see the runtimes documentation.
- Create your first Routing Middleware
- Redirect users based on URLs
- Add conditional logic to handle different scenarios
- Configure which paths your Routing Middleware runs on
- A Vercel project
- Basic knowledge of JavaScript/TypeScript
The following steps will guide you through creating your first Routing Middleware.
Create a file called
middleware.ts
in your project root (same level as yourpackage.json
) and add the following code:middleware.tsexport const config = { runtime: 'nodejs', // defaults to 'edge' }; export default function middleware(request: Request) { console.log('Request to:', request.url); return new Response('Logging request URL from Middleware'); }
- Every request to your site will trigger this function
- You log the request URL to see what's being accessed
- You return a response to prove the middleware is running
Deploy your project and visit any page. You should see "Logging request URL from Middleware" instead of your normal page content.
To redirect users based on their URL, add a new route to your project called
/blog
, and modify yourmiddleware.ts
to include a redirect condition.middleware.tsexport const config = { runtime: 'nodejs', // defaults to 'edge' }; export default function middleware(request: Request) { const url = new URL(request.url); // Redirect old blog path to new one if (url.pathname === '/old-blog') { return new Response(null, { status: 302, headers: { Location: '/blog' }, }); } // Let other requests continue normally return new Response('Other pages work normally'); }
- You use
new URL(request.url)
to parse the incoming URL - You check if the path matches
/old-blog
- If it does, you return a redirect response (status 302)
- The
Location
header tells the browser where to go
Try visiting
/old-blog
- you should be redirected to/blog
.- You use
By default, Routing Middleware runs on every request. To limit it to specific paths, you can use the
config
object:middleware.tsexport const config = { runtime: 'nodejs', // defaults to 'edge' }; export default function middleware(request: Request) { const url = new URL(request.url); // Only handle specific redirects if (url.pathname === '/old-blog') { return new Response(null, { status: 302, headers: { Location: '/blog' }, }); } return new Response('Middleware processed this request'); } // Configure which paths trigger the Middleware export const config = { matcher: [ // Run on all paths except static files '/((?!_next/static|_next/image|favicon.ico).*)', // Or be more specific: // '/blog/:path*', // '/api/:path*' ], };
- The
matcher
array defines which paths trigger your Routing Middleware - The regex excludes static files (images, CSS, etc.) for better performance
- You can also use simple patterns like
/blog/:path*
for specific sections
See the API Reference for more details on the
config
object and matcher patterns.- The
When things don't work as expected:
- Check the logs: Use
console.log()
liberally and check your Vercel dashboard Logs tab - Test the matcher: Make sure your paths are actually triggering the Routing Middleware
- Verify headers: Log
request.headers
to see what's available - Test locally: Routing Middleware works in development too so you can debug before deploying
middleware.tsexport const config = { runtime: 'nodejs', // defaults to 'edge' }; export default function middleware(request: Request) { // Debug logging console.log('URL:', request.url); console.log('Method:', request.method); console.log('Headers:', Object.fromEntries(request.headers.entries())); // Your functions logic here... }
- Check the logs: Use
Learn more about Routing Middleware by exploring the following resources:
Was this helpful?