Middleware-Based Route Protection
Use Next.js middleware and auth callbacks to redirect unauthenticated users at the edge.
Middleware-Based Route Protection is a free React Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the React Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
What Is Next.js Middleware?
Middleware runs at the edge before a request reaches a route. It can redirect, rewrite, or add headers — ideal for auth checks without loading server components.
Creating Middleware
Create middleware.ts at the project root. Export a middleware function and a config matcher.
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const token = request.cookies.get('auth-token')?.value;
if (!token) {
return NextResponse.redirect(new URL('/login', request.url));
}
return NextResponse.next();
}
export const config = {
matcher: ['/dashboard/:path*', '/profile/:path*'],
};Matcher Patterns
The matcher array uses path patterns. Use :path* for any sub-path, or exclude paths with a negative lookahead.
export const config = {
matcher: [
// Protect all routes except public ones:
'/((?!login|register|_next|api/auth|favicon.ico).*)',
],
};Auth.js Middleware Integration
Auth.js (v5) provides a ready-made middleware export. Re-export it from middleware.ts with a matcher.
// middleware.ts
export { auth as middleware } from '@/auth';
export const config = {
matcher: ['/dashboard/:path*', '/settings/:path*'],
};Checking JWT in Middleware
Verify a JWT token in middleware using the jose library (edge-compatible — no Node.js crypto module).
import { jwtVerify } from 'jose';
export async function middleware(request: NextRequest) {
const token = request.cookies.get('token')?.value;
if (!token) return NextResponse.redirect(new URL('/login', request.url));
try {
await jwtVerify(token, new TextEncoder().encode(process.env.JWT_SECRET));
return NextResponse.next();
} catch {
return NextResponse.redirect(new URL('/login', request.url));
}
}Role-Based Middleware
Read the user role from the token and redirect to an unauthorized page if the role is insufficient.
const { payload } = await jwtVerify(token, secret);
if (request.nextUrl.pathname.startsWith('/admin') && payload.role !== 'admin') {
return NextResponse.redirect(new URL('/unauthorized', request.url));
}Passing Data to Route Handlers
Set a request header inside middleware to pass decoded user data to server components without re-fetching the token.
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;
// In a Server Component:
import { headers } from 'next/headers';
const userId = headers().get('x-user-id');Rewriting URLs in Middleware
Use NextResponse.rewrite() to serve a different page for a URL without changing the browser's address bar — useful for A/B tests or feature flags.
const isInExperiment = Math.random() > 0.5;
if (isInExperiment) {
return NextResponse.rewrite(new URL('/home-v2', request.url));
}Geo and IP in Middleware
Access request geo-data and IP from the NextRequest object for region-based redirects or blocking.
const country = request.geo?.country ?? 'US';
if (country === 'XX') {
return NextResponse.redirect(new URL('/region-blocked', request.url));
}Middleware Performance
Middleware runs on every matched request at the edge. Keep it lightweight — avoid heavy computations or large imports. Use edge-compatible libraries only.
Combining Auth and Public Routes
A common pattern: protect everything except a specific allow-list of public paths checked before the auth logic.
const PUBLIC_PATHS = ['/login', '/register', '/about'];
const isPublic = PUBLIC_PATHS.some(p => request.nextUrl.pathname.startsWith(p));
if (isPublic) return NextResponse.next();
// Auth check for non-public routes
const token = request.cookies.get('token')?.value;
if (!token) return NextResponse.redirect(new URL('/login', request.url));Quick Check
Which library should you use to verify JWTs inside Next.js middleware instead of Node's crypto module?
Recap
Create middleware.ts at the project root with a matcher config. Check auth tokens with edge-compatible jose, redirect unauthenticated users, and pass decoded data to server components via response headers. Keep middleware fast and dependency-light.
Frequently asked questions
Is the “Middleware-Based Route Protection” lesson free?
Yes — the full text of “Middleware-Based Route Protection” is free to read here on the web, and the React Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the React Academy course, upgrade to CoddyKit PRO.
What will I learn in “Middleware-Based Route Protection”?
Use Next.js middleware and auth callbacks to redirect unauthenticated users at the edge. You practise React Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start React Academy?
No prior experience is required. React Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Middleware-Based Route Protection” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this React Academy lesson?
Yes. Every React Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Setting Up Auth.js in Next.js App Router
- Session Management & useSession Hook
- Credentials Provider & Custom Login
- Middleware-Based Route Protection