Mutations, APIs and security · Lesson 11 of 16
Proxy (formerly Middleware)
Code that runs before each request: redirects, route protection and headers.
A proxy.ts file at the project root runs before any request reaches a page. It can redirect (not signed in? go to /login), rewrite (serve a different page without changing the URL), or set headers and cookies. In Next.js 16 this file was renamed from middleware.ts to proxy.ts; the old name still works but is deprecated.
// proxy.ts (project root)
import { NextResponse, type NextRequest } from "next/server"
const PROTECTED = ["/dashboard", "/classroom", "/settings"]
export function proxy(request: NextRequest) {
const { pathname } = request.nextUrl
const hasSession = request.cookies.has("sb-access-token")
if (PROTECTED.some((p) => pathname === p || pathname.startsWith(p + "/")) && !hasSession) {
const login = new URL("/login", request.url)
login.searchParams.set("next", pathname) // come back here after login
return NextResponse.redirect(login)
}
return NextResponse.next()
}
// Only run on these paths (skip static files and images)
export const config = {
matcher: ["/((?!_next/static|_next/image|favicon.ico|.*\\.png$).*)"],
}Request: GET /dashboard
proxy.ts: is there a session?
no → redirect to /login?next=/dashboard
yes → the page (which must check again)
Complete the code
Complete it so anyone opening /old-courses is sent to /courses.
export function proxy(request: NextRequest) { if (request.nextUrl.pathname === "/old-courses") { return NextResponse.(new URL("/courses", request.url)) } return NextResponse.() }
Exercise
Write decide(path, role) like a proxy: if the path starts with /admin and the role isn't admin, return redirect:/dashboard. If it starts with /dashboard and there's no role (null), return redirect:/login. Otherwise return next.
redirect:/dashboard next redirect:/login next
function decide(path, role) {
return "next"
}
console.log(decide("/admin/users", "student"))
console.log(decide("/admin/users", "admin"))
console.log(decide("/dashboard", null))
console.log(decide("/courses", null))Learn more from
Played 0 of 2 games
Sign in to save your progress and earn XP.