Claude Code Plugins

Community-maintained marketplace

Feedback

migrating-middleware-to-proxy

@djankies/claude-configs
0
0

Teach middleware.ts to proxy.ts migration in Next.js 16. Use when migrating middleware, encountering middleware errors, or implementing request proxying.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name migrating-middleware-to-proxy
description Teach middleware.ts to proxy.ts migration in Next.js 16. Use when migrating middleware, encountering middleware errors, or implementing request proxying.
allowed-tools Read, Write, Edit, Glob, TodoWrite
version 1.0.0

MIGRATION: middleware.ts to proxy.ts

Overview

Next.js 16 renames middleware.ts to proxy.ts and the middleware export to proxy. This is a breaking change with security implications (CVE-2025-29927).

Why This Change Matters

CVE-2025-29927: Middleware-based authentication is fundamentally broken in Next.js. Middleware cannot reliably protect routes because:

  • Middleware runs at the edge, but authentication state lives in databases/sessions
  • Race conditions between middleware checks and route handlers
  • Middleware can be bypassed through direct route access
  • Edge runtime limitations prevent proper session verification

The rename to "proxy" clarifies that this API is for request/response manipulation, not security.

Migration Steps

1. Rename the File

# Old location
src/middleware.ts

# New location
src/proxy.ts

2. Rename the Export

Before (Next.js 15):

export function middleware(request: NextRequest) {
  return NextResponse.next();
}

export const config = {
  matcher: ['/api/:path*', '/dashboard/:path*'],
};

After (Next.js 16):

export function proxy(request: NextRequest) {
  return NextResponse.next();
}

export const config = {
  matcher: ['/api/:path*', '/dashboard/:path*'],
};

3. Update Configuration

If using next.config.js or next.config.ts:

const nextConfig = {
  experimental: {
  },
};

No configuration changes needed for proxy. The framework detects proxy.ts automatically.

Security Migration

If you were using middleware for authentication, you must migrate to route-level protection.

Before (Insecure)

export function middleware(request: NextRequest) {
  const token = request.cookies.get('auth-token');

  if (!token) {
    return NextResponse.redirect(new URL('/login', request.url));
  }

  return NextResponse.next();
}

export const config = {
  matcher: ['/dashboard/:path*'],
};

After (Secure)

proxy.ts:

export function proxy(request: NextRequest) {
  const response = NextResponse.next();

  response.headers.set('x-custom-header', 'value');

  return response;
}

app/dashboard/layout.tsx:

import { redirect } from 'next/navigation';
import { verifySession } from '@/lib/auth';

export default async function DashboardLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  const session = await verifySession();

  if (!session) {
    redirect('/login');
  }

  return <>{children}</>;
}

Key differences:

  • Authentication logic moves to Server Components
  • Session verification happens in the same runtime as data access
  • No race conditions between auth check and data fetch
  • Can access database/session store reliably

Valid Use Cases for proxy.ts

Use proxy.ts for:

  1. Request/response header manipulation

    export function proxy(request: NextRequest) {
      const response = NextResponse.next();
      response.headers.set('x-frame-options', 'DENY');
      return response;
    }
    
  2. Request logging/monitoring

    export function proxy(request: NextRequest) {
      console.log(`${request.method} ${request.url}`);
      return NextResponse.next();
    }
    
  3. URL rewriting

    export function proxy(request: NextRequest) {
      if (request.nextUrl.pathname === '/old-path') {
        return NextResponse.rewrite(new URL('/new-path', request.url));
      }
      return NextResponse.next();
    }
    
  4. Geolocation routing

    export function proxy(request: NextRequest) {
      const country = request.geo?.country;
      if (country === 'US') {
        return NextResponse.rewrite(new URL('/us', request.url));
      }
      return NextResponse.next();
    }
    

Do NOT Use proxy.ts For

  • Authentication/authorization checks
  • Session validation
  • Database queries
  • Complex business logic
  • Rate limiting (use route handlers instead)

Migration Checklist

  • Rename middleware.ts to proxy.ts
  • Rename middleware export to proxy
  • Remove authentication logic from proxy
  • Move authentication to Server Components/Route Handlers
  • Test that routes are properly protected
  • Verify edge cases (direct route access, API routes, etc.)
  • Update tests that reference middleware

Common Errors

Error: "middleware is not exported"

You forgot to rename the export from middleware to proxy.

Error: "proxy is not a function"

Ensure you're exporting a function named proxy, not a default export.

Error: "Cannot access database in proxy"

Proxy runs at the edge runtime. Move database access to route handlers or Server Components.

Additional Resources

  • CVE-2025-29927: Next.js Middleware Authentication Vulnerability
  • Next.js 16 Migration Guide: Proxy API
  • Next.js Security Best Practices: Route-Level Protection