nextjs-middleware
When you need to run code before a request completes: auth checks, redirects, headers, A/B testing. **Version Context**: Next.js 16.0+ uses `proxy.ts` (replaces `middleware.ts` from v15 and earlier).
When & Why to Use This Skill
This Claude skill provides comprehensive guidance and optimized code patterns for implementing Next.js Middleware and the new Next.js 16+ Proxy system. It enables developers to intercept and manage the request-response lifecycle at the edge, facilitating robust authentication, dynamic redirects, and custom header manipulation. The skill specifically addresses the architectural shift from middleware.ts to proxy.ts in Next.js 16, ensuring developers maintain high performance and security standards.
Use Cases
- Authentication and Authorization: Protecting sensitive routes by verifying session tokens or cookies before a request reaches the page or API.
- Dynamic Redirects and Rewrites: Implementing SEO-friendly URL migrations or conditional routing based on user roles, geolocation, or device type.
- Security Header Management: Automatically injecting essential HTTP security headers like Content Security Policy (CSP) and X-Frame-Options to harden the application.
- Edge-side A/B Testing: Distributing traffic between different page versions or feature sets using cookies to perform zero-latency experimentation.
- Next.js Version Migration: Providing a clear path and automated patterns for transitioning legacy middleware.ts (v15) to the modern proxy.ts (v16+) architecture.
| name | nextjs-middleware |
|---|---|
| description | When you need to run code before a request completes: auth checks, redirects, headers, A/B testing. **Version Context**: Next.js 16.0+ uses `proxy.ts` (replaces `middleware.ts` from v15 and earlier). |
| version | 1.1.0 |
| tokens | ~550 |
| confidence | high |
| - https | //nextjs.org/docs/app/building-your-application/routing/middleware |
| last_validated | 2025-12-10 |
| next_review | 2025-12-24 |
| tags | [nextjs, middleware, proxy, auth, routing, frontend] |
When to Use
When you need to run code before a request completes: auth checks, redirects, headers, A/B testing.
Version Context: Next.js 16.0+ uses proxy.ts (replaces middleware.ts from v15 and earlier).
Patterns
Basic Proxy (Next.js 16+)
// proxy.ts (root of project)
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function proxy(request: NextRequest) {
// Runs on EVERY matched route
return NextResponse.next();
}
// Match specific routes
export const config = {
matcher: ['/dashboard/:path*', '/api/:path*']
};
Legacy Middleware (Next.js 15 and earlier)
// middleware.ts (root of project)
export function middleware(request: NextRequest) {
return NextResponse.next();
}
export const config = {
matcher: ['/dashboard/:path*']
};
Migration: Run npx @next/codemod@canary middleware-to-proxy . to auto-migrate.
Auth Redirect
export function proxy(request: NextRequest) {
const token = request.cookies.get('session');
if (!token && request.nextUrl.pathname.startsWith('/dashboard')) {
return NextResponse.redirect(new URL('/login', request.url));
}
return NextResponse.next();
}
Add Headers
export function proxy(request: NextRequest) {
const response = NextResponse.next();
// Add security headers
response.headers.set('X-Frame-Options', 'DENY');
response.headers.set('X-Content-Type-Options', 'nosniff');
return response;
}
Matcher Patterns
export const config = {
matcher: [
// Match all paths except static files
'/((?!_next/static|_next/image|favicon.ico).*)',
// Match specific paths
'/dashboard/:path*',
'/api/:path*',
]
};
Advanced Matcher with Conditions
export const config = {
matcher: [
{
source: '/api/:path*',
locale: false,
has: [{ type: 'header', key: 'Authorization' }],
missing: [{ type: 'cookie', key: 'session' }],
},
],
};
Anti-Patterns
- Heavy computation in proxy (runs on every request)
- Database queries (use Edge-compatible clients only)
- Large dependencies (bundle size matters at edge)
- Forgetting matcher (runs on ALL routes by default)
- Using
middleware.tsin Next.js 16+ (useproxy.tsinstead)
Verification Checklist
- Matcher configured (not running on static files)
- No heavy computation or DB calls
- Auth redirects tested
- Headers properly set
- Using
proxy.tsfor Next.js 16+,middleware.tsfor v15 and earlier