/nextjs-middleware-creator
Create optimized Next.js middleware with authentication, rate limiting, and routing logic
$ npx -y skills add davila7/claude-code-templates --agent claude-codeHow it fires
How this command gets triggered: by you, by Claude, or both.
- Fires itselfClaude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/nextjs-middleware-creator
Context preview
What this command does when you run it.
Create optimized Next.js middleware with authentication, rate limiting, and routing logic
Command definition
nextjs-middleware-creator.mdallowed-tools: Read, Write, Edit
argument-hint: [middleware-type] [--auth] [--rate-limit] [--redirect] [--rewrite]
description: Create optimized Next.js middleware with authentication, rate limiting, and routing logic
Next.js Middleware Creator
**Middleware Type**: $ARGUMENTS
Current Project Analysis
Project Structure
- Next.js config: @next.config.js
- Existing middleware: @middleware.ts or @middleware.js (if exists)
- App directory: @app/ (if App Router)
- Auth configuration: @auth.config.ts or @lib/auth/ (if exists)
Framework Detection
- Package.json: @package.json
- TypeScript config: @tsconfig.json (if exists)
- Authentication libraries: Detect NextAuth.js, Auth0, or custom auth
Middleware Implementation Strategy
1. Middleware File Structure
Create comprehensive middleware at project root:
middleware.ts # Main middleware file
lib/middleware/ # Middleware utilities
├── auth.ts # Authentication middleware
├── rateLimit.ts # Rate limiting logic
├── redirects.ts # Redirect rules
├── rewrites.ts # URL rewriting
├── cors.ts # CORS handling
├── security.ts # Security headers
└── types.ts # TypeScript types
2. Base Middleware Template
// middleware.ts
import { NextRequest, NextResponse } from 'next/server';
import { authMiddleware } from './lib/middleware/auth';
import { rateLimitMiddleware } from './lib/middleware/rateLimit';
import { securityMiddleware } from './lib/middleware/security';
import { redirectMiddleware } from './lib/middleware/redirects';
export async function middleware(request: NextRequest) {
const { pathname } = request.nextUrl;
// Apply security headers first
let response = await securityMiddleware(request);
// Apply rate limiting
const rateLimitResult = await rateLimitMiddleware(request);
if (rateLimitResult) return rateLimitResult;
// Handle authentication for protected routes
if (isProtectedRoute(pathname)) {
const authResult = await authMiddleware(request);
if (authResult) return authResult;
}
// Handle redirects
const redirectResult = await redirectMiddleware(request);
if (redirectResult) return redirectResult;
// Apply additional headers to response
if (response) {
return response;
}
return NextResponse.next();
}
function isProtectedRoute(pathname: string): boolean {
const protectedPaths = ['/dashboard', '/admin', '/api/protected'];
return protectedPaths.some(path => pathname.startsWith(path));
}
export const config = {
matcher: [
// Match all request paths except static files and images
'/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
],
};Middleware Components
1. Authentication Middleware
// lib/middleware/auth.ts
import { NextRequest, NextResponse } from 'next/server';
import { jwtVerify } from 'jose';
const JWT_SECRET = new TextEncoder().encode(
process.env.JWT_SECRET || 'your-secret-key'
);
export async function authMiddleware(request: NextRequest) {
try {
// Get token from cookies or Authorization header
const token = request.cookies.get('auth-token')?.value ||
request.headers.get('authorization')?.replace('Bearer ', '');
if (!token) {
return redirectToLogin(request);
}
// Verify JWT token
const { payload } = await jwtVerify(token, JWT_SECRET);
// Add user info to headers for downstream use
const response = NextResponse.next();
response.headers.set('x-user-id', payload.sub as string);
response.headers.set('x-user-role', payload.role as string);
return response;
} catch (error) {
console.error('Auth middleware error:', error);
return redirectToLogin(request);
}
}
function redirectToLogin(request: NextRequest) {
const loginUrl = new URL('/login', request.url);
loginUrl.searchParams.set('callbackUrl', request.url);
return NextResponse.redirect(loginUrl);
}
// Role-based access control
export function requireRole(allowedRoles: string[]) {
return async function roleMiddleware(request: NextRequest) {
const userRole = request.headers.get('x-user-role');
if (!userRole || !allowedRoles.includes(userRole)) {
return new NextResponse('Forbidden', { status: 403 });
}
return NextResponse.next();
};
}2. Rate Limiting Middleware
// lib/middleware/rateLimit.ts
import { NextRequest, NextResponse } from 'next/server';
// Simple in-memory store (use Redis in production)
const requestCounts = new Map<string, { count: number; resetTime: number }>();
interface RateLimitConfig {
windowMs: number; // Time window in milliseconds
maxRequests: number; // Max requests per window
keyGenerator?: (request: NextRequest) => string;
}
const defaultConfig: RateLimitConfig = {
windowMs: 15 * 60 * 1000, // 15 minutes
maxRequests: 100, // 100 requests per 15 minutes
};
export async function rateLimitMiddleware(
request: NextRequest,
config: RateLimitConfig = defaultConfig
) {
const key = config.keyGenerator
? config.keyGenerator(request)
: getClientIP(request);
const now = Date.now();
const clientData = requestCounts.get(key);
// Reset window if expired
if (!clientData || now > clientData.resetTime) {
requestCounts.set(key, {
count: 1,
resetTime: now + config.windowMs
});
return null; // Allow request
}
// Increment counter
clientData.count++;
// Check if limit exceeded
if (clientData.count > config.maxRequests) {
const resetTime = Math.ceil((clientData.resetTime - now) / 1000);
return new NextResponse('Rate limit exceeded', {
status: 429,
headers: {
'X-RateLimit-Limit': config.maxRequests.toString(),
'X-RateLimit-Remaining': '0',
'X-RateLimit-Reset': resetTime.toString(),
'Retry-ARead more
allowed-tools: Read, Write, Edit argument-hint: [middleware-type] [--auth] [--rate-limit] [--redirect] [--rewrite] description: Create optimized Next.js middleware with authentication, rate limiting, and routing logic
Next.js Middleware Creator
**Middleware Type**: $ARGUMENTS
Current Project Analysis
Project Structure
- Next.js config: @next.config.js
- Existing middleware: @middleware.ts or @middleware.js (if exists)
- App directory: @app/ (if App Router)
- Auth configuration: @auth.config.ts or @lib/auth/ (if exists)
Framework Detection
- Package.json: @package.json
- TypeScript config: @tsconfig.json (if exists)
- Authentication libraries: Detect NextAuth.js, Auth0, or custom auth
Middleware Implementation Strategy
1. Middleware File Structure
Create comprehensive middleware at project root:
middleware.ts # Main middleware file lib/middleware/ # Middleware utilities ├── auth.ts # Authentication middleware ├── rateLimit.ts # Rate limiting logic ├── redirects.ts # Redirect rules ├── rewrites.ts # URL rewriting ├── cors.ts # CORS handling ├── security.ts # Security headers └── types.ts # TypeScript types
2. Base Middleware Template
// middleware.ts
import { NextRequest, NextResponse } from 'next/server';
import { authMiddleware } from './lib/middleware/auth';
import { rateLimitMiddleware } from './lib/middleware/rateLimit';
import { securityMiddleware } from './lib/middleware/security';
import { redirectMiddleware } from './lib/middleware/redirects';
export async function middleware(request: NextRequest) {
const { pathname } = request.nextUrl;
// Apply security headers first
let response = await securityMiddleware(request);
// Apply rate limiting
const rateLimitResult = await rateLimitMiddleware(request);
if (rateLimitResult) return rateLimitResult;
// Handle authentication for protected routes
if (isProtectedRoute(pathname)) {
const authResult = await authMiddleware(request);
if (authResult) return authResult;
}
// Handle redirects
const redirectResult = await redirectMiddleware(request);
if (redirectResult) return redirectResult;
// Apply additional headers to response
if (response) {
return response;
}
return NextResponse.next();
}
function isProtectedRoute(pathname: string): boolean {
const protectedPaths = ['/dashboard', '/admin', '/api/protected'];
return protectedPaths.some(path => pathname.startsWith(path));
}
export const config = {
matcher: [
// Match all request paths except static files and images
'/((?!_next/static|_next/image|favicon.ico|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
],
};Middleware Components
1. Authentication Middleware
// lib/middleware/auth.ts
import { NextRequest, NextResponse } from 'next/server';
import { jwtVerify } from 'jose';
const JWT_SECRET = new TextEncoder().encode(
process.env.JWT_SECRET || 'your-secret-key'
);
export async function authMiddleware(request: NextRequest) {
try {
// Get token from cookies or Authorization header
const token = request.cookies.get('auth-token')?.value ||
request.headers.get('authorization')?.replace('Bearer ', '');
if (!token) {
return redirectToLogin(request);
}
// Verify JWT token
const { payload } = await jwtVerify(token, JWT_SECRET);
// Add user info to headers for downstream use
const response = NextResponse.next();
response.headers.set('x-user-id', payload.sub as string);
response.headers.set('x-user-role', payload.role as string);
return response;
} catch (error) {
console.error('Auth middleware error:', error);
return redirectToLogin(request);
}
}
function redirectToLogin(request: NextRequest) {
const loginUrl = new URL('/login', request.url);
loginUrl.searchParams.set('callbackUrl', request.url);
return NextResponse.redirect(loginUrl);
}
// Role-based access control
export function requireRole(allowedRoles: string[]) {
return async function roleMiddleware(request: NextRequest) {
const userRole = request.headers.get('x-user-role');
if (!userRole || !allowedRoles.includes(userRole)) {
return new NextResponse('Forbidden', { status: 403 });
}
return NextResponse.next();
};
}2. Rate Limiting Middleware
// lib/middleware/rateLimit.ts
import { NextRequest, NextResponse } from 'next/server';
// Simple in-memory store (use Redis in production)
const requestCounts = new Map<string, { count: number; resetTime: number }>();
interface RateLimitConfig {
windowMs: number; // Time window in milliseconds
maxRequests: number; // Max requests per window
keyGenerator?: (request: NextRequest) => string;
}
const defaultConfig: RateLimitConfig = {
windowMs: 15 * 60 * 1000, // 15 minutes
maxRequests: 100, // 100 requests per 15 minutes
};
export async function rateLimitMiddleware(
request: NextRequest,
config: RateLimitConfig = defaultConfig
) {
const key = config.keyGenerator
? config.keyGenerator(request)
: getClientIP(request);
const now = Date.now();
const clientData = requestCounts.get(key);
// Reset window if expired
if (!clientData || now > clientData.resetTime) {
requestCounts.set(key, {
count: 1,
resetTime: now + config.windowMs
});
return null; // Allow request
}
// Increment counter
clientData.count++;
// Check if limit exceeded
if (clientData.count > config.maxRequests) {
const resetTime = Math.ceil((clientData.resetTime - now) / 1000);
return new NextResponse('Rate limit exceeded', {
status: 429,
headers: {
'X-RateLimit-Limit': config.maxRequests.toString(),
'X-RateLimit-Remaining': '0',
'X-RateLimit-Reset': resetTime.toString(),
'Retry-AReady-to-use configurations for Anthropic's Claude Code. A comprehensive collection of AI agents, custom commands, settings, hooks, external integrations (MCPs), and project templates to enhance your development workflow.
Repo: davila7/claude-code-templates
Other commands on claude-code-templates.
- /cleanup-cache
Clean system caches (npm, Homebrew, Yarn, browsers, Python/ML) to free disk space
Open command - /create-blog-article
Create an SEO-optimized blog article for a Claude Code component with AI-generated cover image
Open command - /lint
Run Python code linting and formatting tools.
Open command - /test
Run Python tests with pytest, unittest, or other testing frameworks.
Open command - /worktree-check
Check current worktree status, branch, and assigned task
Open command - /worktree-cleanup
Clean up merged worktrees and their branches
Open command

