Next.js 13基于Locale重写URL遇404问题求助
Next.js Locale URL重写失效问题解析
问题背景
尝试通过middleware.js获取Locale来重写URL,但URL未被重写且返回404页面。直接访问localhost:3000/en这类带Locale的路径时,响应正常且功能符合预期。将app目录从src文件夹移到项目根目录后问题解决,疑问其原因。
相关代码与结构
middleware.js(原项目根目录下)
import { NextResponse } from "next/server"; import { match } from "@formatjs/intl-localematcher"; import Negotiator from "negotiator"; let locales = ["en", "ka", "ru"]; export let defaultLocale = "en"; function getLocale(request) { const headers = new Headers(request.headers); const acceptLanguage = headers.get("accept-language"); if (acceptLanguage) { headers.set("accept-language", acceptLanguage.replaceAll("_", "-")); } const headersObject = Object.fromEntries(headers.entries()); const languages = new Negotiator({ headers: headersObject }).languages(); return match(languages, locales, defaultLocale); } export function middleware(request) { let locale = getLocale(request) ?? defaultLocale; const pathname = request.nextUrl.pathname; const newUrl = new URL(`/${locale}${pathname}`, request.nextUrl); // e.g. incoming request is /products // The new URL is now /en/products return NextResponse.rewrite(newUrl); } export const config = { matcher: ["/((?!_next|api|favicon.ico).*)"] };
原文件结构
src -app --[lang] ---(public) ----layout.jsx ----page.jsx
原因分析
核心问题是Next.js对src/目录的约定规则:
- Next.js允许将整个应用代码放在
src/目录下,此时src/会被视为应用的根目录,所有路由、中间件等应用相关文件都需要在src/内部。 - 你之前将
middleware.js放在了项目根目录,而路由文件在src/app/下。当中间件重写URL为/en/products时,Next.js会默认去项目根目录的app/[lang]/...路径查找路由,但实际路由文件在src/内部,无法匹配,因此返回404。 - 当把
app目录移到项目根目录后,中间件和路由目录处于同一层级,重写后的URL能正确对应到app/[lang]/...的路由文件,功能自然恢复正常。
替代解决方案(无需移动app目录)
如果想继续保留src/目录的结构,只需将根目录的middleware.js移动到src/目录下(即src/middleware.js),让中间件和路由目录处于同一应用根层级,即可解决URL重写后的404问题。
内容的提问来源于stack exchange,提问作者David Henry
相关产品推荐
相关产品推荐

