0
0
NextjsHow-ToBeginner · 3 min read

How to Use Middleware for Rewrite in Next.js

In Next.js, use middleware.ts to intercept requests and rewrite URLs by returning a NextResponse.rewrite() with the new path. This lets you change the request URL before it reaches your pages or API routes.
📐

Syntax

The middleware function runs on every request matching its matcher pattern. Use NextResponse.rewrite(url) to rewrite the request URL.

  • request: The incoming request object.
  • NextResponse.rewrite(url): Returns a response that rewrites the URL to url.
  • matcher: Defines which paths the middleware applies to.
typescript
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  // Rewrite the request URL
  return NextResponse.rewrite(new URL('/new-path', request.url));
}

export const config = {
  matcher: '/old-path/:path*',
};
💻

Example

This example rewrites requests from /blog/:slug to /news/:slug dynamically using middleware.

typescript
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl;

  if (pathname.startsWith('/blog/')) {
    const newPathname = pathname.replace('/blog/', '/news/');
    return NextResponse.rewrite(new URL(newPathname, request.url));
  }

  return NextResponse.next();
}

export const config = {
  matcher: '/blog/:path*',
};
Output
When you visit /blog/my-article, the URL is rewritten internally to /news/my-article and the content from /news/my-article is served.
⚠️

Common Pitfalls

  • Not setting the matcher correctly causes middleware to run on unwanted paths or not at all.
  • Forgetting to return NextResponse.next() when no rewrite is needed can block requests.
  • Using absolute URLs incorrectly in NextResponse.rewrite() can cause errors; always use new URL(path, request.url).
typescript
/* Wrong: Missing matcher, rewrites all requests unintentionally */
import { NextResponse } from 'next/server';
export function middleware(request) {
  return NextResponse.rewrite('/new-path'); // Incorrect usage without URL object
}

/* Right: Use matcher and proper URL object */
import { NextResponse } from 'next/server';
export function middleware(request) {
  return NextResponse.rewrite(new URL('/new-path', request.url));
}
export const config = { matcher: '/old-path/:path*' };
📊

Quick Reference

FeatureDescriptionExample
middleware functionIntercepts requests to rewrite or redirectexport function middleware(request) { ... }
NextResponse.rewrite()Rewrites the request URL internallyreturn NextResponse.rewrite(new URL('/new-path', request.url));
matcher configDefines which paths middleware applies toexport const config = { matcher: '/old-path/:path*' };
NextResponse.next()Continues without changes if no rewritereturn NextResponse.next();

Key Takeaways

Use middleware with NextResponse.rewrite() to change request URLs dynamically in Next.js.
Always define a matcher to limit middleware to specific paths for better performance.
Return NextResponse.next() when no rewrite is needed to avoid blocking requests.
Use new URL(path, request.url) to create correct URLs for rewriting.
Middleware runs before rendering, so rewrites happen server-side and are transparent to users.