Next.js多中间件配置:Clerk仅作用于Dashboard页面
仅对Dashboard页面启用Clerk鉴权并全局配置next-intl国际化
核心思路
你的需求是全局启用国际化,但仅对(admin)路由组下的Dashboard及其子页面做鉴权,因此需要拆分中间件逻辑:
- 用
next-intl中间件处理所有页面的国际化(全局生效) - 单独为Dashboard路径配置Clerk鉴权中间件,仅对目标路径生效
方案一:拆分两个独立中间件(推荐)
这种方式逻辑清晰,后续维护更简单。
1. 全局国际化中间件(middleware.js)
处理所有页面的locale重定向、语言检测等逻辑:
import createMiddleware from "next-intl/middleware"; const intlMiddleware = createMiddleware({ locales: ["en", "fa"], defaultLocale: "fa", }); export default intlMiddleware; export const config = { matcher: ["/((?!.*\\..*|_next).*)", "/", "/(api|trpc)(.*)"], };
2. Dashboard专属鉴权中间件(auth-middleware.js)
仅对Dashboard及其子页面应用Clerk鉴权:
import { authMiddleware } from "@clerk/nextjs"; export default authMiddleware({ // 允许登录页面公开访问,避免未登录时的重定向循环 publicRoutes: ["/:locale/sign-in"], }); export const config = { // 匹配所有Dashboard路径(注意:路由组(admin)不会出现在URL中) matcher: ["/:locale/dashboard/:path*"], };
方案二:单中间件组合逻辑
如果想把所有逻辑放在同一个文件里,可以通过路径判断区分处理:
import { authMiddleware } from "@clerk/nextjs"; import createMiddleware from "next-intl/middleware"; import { NextRequest } from "next/server"; const intlMiddleware = createMiddleware({ locales: ["en", "fa"], defaultLocale: "fa", }); // 定义需要鉴权的路径规则 const protectedPathPattern = /^\/[a-z]{2}\/dashboard\/?.*$/; export default function middleware(req: NextRequest) { // 先执行国际化处理 const intlResponse = intlMiddleware(req); if (intlResponse) return intlResponse; // 检查当前路径是否属于Dashboard if (protectedPathPattern.test(req.nextUrl.pathname)) { // 对Dashboard路径应用Clerk鉴权 return authMiddleware({ publicRoutes: ["/:locale/sign-in"], })(req); } // 其他路径直接放行 return Response.next(); } export const config = { matcher: ["/((?!.*\\..*|_next).*)", "/", "/(api|trpc)(.*)"], };
关键注意点
- Next.js的路由组(如
(admin))不会生成URL路径,实际访问路径是/:locale/dashboard而非/:locale/admin/dashboard - 必须将登录页面(
/sign-in)加入publicRoutes,否则用户未登录时会陷入重定向循环 - 两种方案都能保证所有页面优先处理国际化,再对目标路径执行鉴权
内容的提问来源于stack exchange,提问作者Mahdi
相关产品推荐
相关产品推荐

