Next.js App目录下通过中间件触发not-found页面的方法
在Next.js App目录中通过Middleware校验多语言路由并复用not-found.tsx
实现步骤:
定义允许的语言列表
先在middleware.ts中声明支持的语言数组:const ALLOWED_LANGUAGES = ['en', 'vi'] as const;配置Middleware的路由匹配规则
让Middleware只作用于带[lang]参数的路由,同时排除不需要校验的API路由、静态资源等:export const config = { matcher: [ /* * 匹配所有带[lang]前缀的路由,排除: * - /api/ 开头的API路由 * - 静态文件(如.js, .css, .png等) * - Next.js内部文件(如/_next/) */ '/((?!api|_next/static|_next/image|favicon.ico).*)', ], };编写语言校验逻辑
解析路由中的lang参数,校验合法性,不合法时触发notFound()让Next.js自动渲染根目录的not-found.tsx:import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; import { notFound } from 'next/navigation'; const ALLOWED_LANGUAGES = ['en', 'vi'] as const; export function middleware(request: NextRequest) { // 从路由路径中提取lang参数 const lang = request.nextUrl.pathname.split('/')[1]; // 校验lang是否存在且在允许列表内 if (!lang || !ALLOWED_LANGUAGES.includes(lang as (typeof ALLOWED_LANGUAGES)[number])) { // 触发not-found,自动调用app/not-found.tsx notFound(); } // 校验通过,继续处理请求 return NextResponse.next(); } export const config = { matcher: [ '/((?!api|_next/static|_next/image|favicon.ico).*)', ], };确保根目录存在
not-found.tsx
在app目录下创建该文件,示例内容:export default function NotFound() { return ( <div style={{ padding: '2rem', textAlign: 'center' }}> <h1>404 - 页面不存在</h1> <p>你输入的语言参数不合法,或目标页面未找到</p> </div> ); }
关键说明:
notFound()函数需从next/navigation导入,它会自动调用当前路由层级下的not-found.tsx,根目录的该文件会作为全局404页面生效。- 若需要更精准匹配多语言路由,可将matcher调整为
'/[lang]/:path*',仅作用于带[lang]前缀的二级及以下路由。 - 通过类型断言
lang as (typeof ALLOWED_LANGUAGES)[number]避免TypeScript类型报错。
内容的提问来源于stack exchange,提问作者kan
相关产品推荐
相关产品推荐

