In 2023 I built a Next.js 13 dashboard behind Clerk , and every route's protection lived in one file: authMiddleware in middleware.ts , deny by default. That code no longer runs on current versions. authMiddleware was replaced in @clerk/nextjs v5 by clerkMiddleware() , which protects nothing by default. Next.js 16 renamed middleware.ts to proxy.ts . And as of November 2026 Clerk deprecates gating routes in that file at all: each page, Route Handler and Server Function calls await auth.protect() itself.
This post walks the demo's real code from the 2023 version to the current one, and explains why the check moved.
What did the 2023 middleware do?
This is the whole of the demo's auth wiring, on next 13.4.7 and @clerk/nextjs 4.21:
// middleware.ts import { authMiddleware } from '@clerk/nextjs'
export default authMiddleware ( { publicRoutes : [ '/api/:path*' ] , } )
export const config = { matcher : [ '/((?!.*\\..*|_next).*)' , '/' , '/(api|trpc)(.*)' ] , }
Enter fullscreen mode
Exit fullscreen…