Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Proxy: code before the request

A proxy is a function that runs before Next.js renders a page or calls an API. It sees the request and can let it through, redirect it to another address or add headers. It is usually used for a quick login check and language selection. Before Next.js 16 this was called middleware — older articles show a middleware.ts file.

Where the file lives

The proxy is a single proxy.ts file in the project root, next to the app/ folder, not inside it. Let us start with a simple request log:

// proxy.ts
import { NextResponse, type NextRequest } from 'next/server';
 
export function proxy(request: NextRequest) {
  console.log('Request:', request.nextUrl.pathname);
  return NextResponse.next();
}

The function is called proxy. NextResponse.next() lets the request through. Open a few pages — lines like "Request: /posts" appear in the npm run dev terminal.

Limiting addresses: matcher

Without settings, the proxy runs on every request, including images and script files. A config object with a matcher field keeps only the addresses you need:

// proxy.ts (fragment)
export const config = {
  matcher: ['/posts/new', '/admin/:path*'],
};

:path* means "and everything nested": /admin, /admin/users, /admin/users/5.

Redirecting without a login

Let us close the add-post form to visitors who have not logged in. The sign of a login is a session cookie — the next lesson covers setting it:

// proxy.ts
import { NextResponse, type NextRequest } from 'next/server';
 
export function proxy(request: NextRequest) {
  const session = request.cookies.get('session');
 
  if (!session) {
    return NextResponse.redirect(new URL('/login', request.url));
  }
 
  return NextResponse.next();
}
 
export const config = {
  matcher: ['/posts/new'],
};

Open /posts/new in a private window — the browser lands on /login. The redirect method takes a full address, so it is built with new URL from the current request.

What else the proxy can do

TaskHow
Read a cookierequest.cookies.get('name')
Read a headerrequest.headers.get('accept-language')
RedirectNextResponse.redirect(url)
Show another page without changing the addressNextResponse.rewrite(url)
Add a response headerresponse.headers.set('x-name', 'value')

Limitations

The proxy must be fast: it runs on every matching request. In Next.js 16 it runs in the Node.js runtime, but slow database queries still do not belong here. The proxy is for a quick preliminary check such as whether a cookie exists; the full permission check happens in the page or the server action. For simple permanent redirects without conditions, the redirects setting in next.config.ts is more convenient.

Common mistake

Copying a middleware.ts file with a middleware function from an older article. In Next.js 16 that name is deprecated: the build shows a warning, and future versions will stop supporting it. Name the file proxy.ts and the function proxy, and put the file in the project root, not in app/.

Thanks for reading!

Donate to the site — we work hard for you.