Free tutorials & notes in Hindi & English · Clean code examples 🧰 Free PDF & Image Tools →
🟣 Data, Server & APIs  ·  Lesson 25

Proxy (Middleware) & Redirects

What is proxy.js?

proxy.js is a single file in your project root (next to app/) whose proxy() function runs before a request reaches your pages. It can let the request continue, redirect it, rewrite it, or add headers and cookies. Before Next.js 16 this was called middleware.js.

Where it runs in the request

BrowserGET /course/cproxy.jsdecideredirect / rewriteor next()app/ routepage renders
proxy sits in front of every matched route

Example 1: redirect old URLs (EduSite)

Suppose your old site used /course/python-ai and the new one uses /courses/python-ai. Google has the old URLs indexed — a permanent redirect transfers their ranking.

JS – proxy.js
// proxy.js  (project root – EduSite, complete file)
import { NextResponse } from 'next/server'

// Old URLs like /course/python-ai are permanently moved to /courses/python-ai.
export function proxy(request) {
  const { pathname } = request.nextUrl
  if (pathname.startsWith('/course/')) {
    const url = request.nextUrl.clone()
    url.pathname = pathname.replace('/course/', '/courses/')
    return NextResponse.redirect(url, 308)       // 308 = permanent (SEO keeps ranking)
  }
  return NextResponse.next()                     // continue normally
}

export const config = { matcher: ['/course/:path*'] }
Terminal – check the redirect
$ curl -I http://localhost:3000/course/python-ai HTTP/1.1 308 Permanent Redirect location: /courses/python-ai

The matcher config

Without a matcher, proxy runs for every request, including images and JS files. Limit it:

JS – matcher patterns
export const config = {
  matcher: [
    '/dashboard/:path*',          // /dashboard and everything below
    '/admin/:path*',
    // everything EXCEPT static files, images and API:
    '/((?!api|_next/static|_next/image|favicon.ico|.*\\.png$).*)',
  ],
}

Example 2: rewrite (maintenance page)

JS – proxy.js rewrite
// proxy.js — show a maintenance page without changing the URL
import { NextResponse } from 'next/server'

export function proxy(request) {
  if (process.env.MAINTENANCE === 'on' && !request.nextUrl.pathname.startsWith('/maintenance')) {
    return NextResponse.rewrite(new URL('/maintenance', request.url))
  }
  return NextResponse.next()
}

redirect()

  • Browser URL changes
  • Two requests
  • Use for moved pages (SEO)

rewrite()

  • Browser URL stays
  • One request
  • Use for A/B tests, maintenance
Redirect vs rewrite

Example 3: headers and cookies

JS – proxy.js headers
// proxy.js — add a header and remember the referral code from ?ref=
import { NextResponse } from 'next/server'

export function proxy(request) {
  const res = NextResponse.next()
  res.headers.set('X-Frame-Options', 'DENY')                   // security header

  const ref = request.nextUrl.searchParams.get('ref')
  if (ref) res.cookies.set('ref', ref, { maxAge: 60 * 60 * 24 * 30 })   // 30 days
  return res
}

Migrating from middleware.js

Terminal + JS
# Next.js provides a codemod:
npx @next/codemod@latest middleware-to-proxy .

// Before (Next.js 15)          // After (Next.js 16)
// middleware.js                // proxy.js
export function middleware(req) { }   →   export function proxy(req) { }

When NOT to use proxy

  • Fixed list of redirects → redirects() in next.config is simpler.
  • Slow work (database queries) → proxy runs on every matched request; keep it fast.
  • As the only security check → also verify in pages/actions (see Auth lesson).

Common mistakes

  • Placing proxy.js inside app/ → it must be at the project root (or src/).
  • Redirect loops (redirecting /login to /login) → exclude the target path.
  • Using 302 for permanent moves → search engines keep the old URL; use 301/308.

Summary

  • proxy.js + export function proxy() runs before routes.
  • Return NextResponse.next(), .redirect() or .rewrite(); add headers/cookies.
  • Always set a matcher and keep logic fast.
✅ Practice

Add a proxy rule that redirects /blogs/:slug to /blog/:slug with 308, and verify it with curl -I.

Frequently Asked Questions

Why was middleware renamed to proxy in Next.js 16?
To make its role clear: it sits in front of your app like a network proxy, deciding to continue, redirect or rewrite a request. The function is now export function proxy() in proxy.js.
What is the difference between redirect and rewrite?
A redirect changes the URL in the browser (the user sees the new URL). A rewrite shows content from another path while the URL stays the same.
Should I use proxy.js or next.config redirects?
For fixed old-to-new URL pairs use redirects() in next.config. Use proxy.js when the decision needs logic: cookies, headers, patterns or geography.
← Next.js Tutorial
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

Next topicEnvironment Variables & next.config Your progress: 25 / 37 (68%) · Lesson 26 / 37 Continue →

How was this lesson?

Your feedback helps us make the content better.

Write a review or suggestion (optional)

After approval, your name and city may appear publicly with your review. Please do not write your email or phone number.

▶ CodingEasily on YouTube

Learn with video lessons in easy Hindi

Featured video: RDBMS Part 3 – Class XI Commerce IT

▶ Subscribe – it’s free