You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 14:10:00