i18next多语言特性干扰NextJS not-found.jsx,所有路径返回200
NextJS国际化(i18next)导致404页面失效的解决办法
问题根源
/[locale]动态路由会匹配任意字符串作为路由参数,导致所有不存在的路径都被该路由捕获,返回首页而非404页面,不管路径带不带locale前缀。
解决方案
1. 校验Locale合法性
在app/[locale]/layout.js(App Router)或pages/[locale]/_app.js(Pages Router)中,先判断传入的locale是否在你的合法语言列表内,不合法则直接触发404:
// App Router 示例 import { notFound } from 'next/navigation'; export default function LocaleLayout({ children, params }) { const validLocales = ['en', 'zh-CN']; // 替换为你的项目支持语言 if (!validLocales.includes(params.locale)) { notFound(); } return <>{children}</>; }
2. 拦截非合法路径(中间件方案)
创建middleware.js,拦截所有请求,区分合法路由与无效路径:
import { NextResponse } from 'next/server'; const validLocales = ['en', 'zh-CN']; const defaultLocale = 'en'; // 根目录下的合法路由(根据你的项目实际路由调整) const validRootPaths = ['/', '/about', '/blog']; export function middleware(request) { const pathname = request.nextUrl.pathname; // 跳过静态资源和API路由 if (pathname.startsWith('/api') || pathname.startsWith('/_next')) return; // 检查是否是合法locale前缀的路径 const hasValidLocalePrefix = validLocales.some( locale => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}` ); if (!hasValidLocalePrefix) { // 非合法根路径,直接重定向到对应locale的404 if (!validRootPaths.includes(pathname)) { const url = new URL(`/${defaultLocale}/404`, request.url); return NextResponse.rewrite(url); } // 合法根路径,自动添加locale前缀重定向 const url = new URL(`/${defaultLocale}${pathname}`, request.url); return NextResponse.redirect(url); } } export const config = { matcher: ['/((?!favicon.ico).*)'], };
3. 确保404页面正确配置
在app/[locale]/not-found.jsx(App Router)下创建自定义404页面,当notFound()被触发时会自动渲染该页面,同时返回404状态码。
验证效果
- 访问
/inexistingroute:会被中间件拦截,重定向到对应locale的404页面,返回404状态码。 - 访问
/invalid-lang/inexistingroute:会被layout中的locale校验触发404,渲染自定义404页面。
内容的提问来源于stack exchange,提问作者Genaro Febbo Yapur
相关产品推荐
相关产品推荐

