Next.js生产环境开启i18n后直接访问子路径返回404问题求助
问题根本原因
- 最常见诱因是使用了
next export做纯静态导出:Next.js的纯静态导出模式会默认给所有locale(包括默认locale)的路径添加前缀,构建产物里所有页面都会生成在对应locale的子目录下,根路径下没有对应页面文件,直接访问不带前缀的路径就会返回404。 - 次要原因是部署环境未适配Next.js的i18n路由规则:如果是自行用Nginx、Apache等服务部署,没有配置对应的重写规则,就无法正确映射不带前缀的路径到默认locale的资源。
- 少数场景是Next.js版本bug:部分低版本Next.js存在i18n路由规则未在生产环境生效的问题。
排查步骤
- 首先查看项目package.json的build命令,确认是否包含
next export指令,确认是否使用纯静态导出模式。 - 查看构建生成的产物目录(默认是out文件夹),确认根路径下是否存在对应页面的html文件,还是所有页面都存放在
/en/、/ru/子目录下。 - 排查部署服务配置,确认是否配置了适配Next.js i18n的重写/重定向规则。
解决方案
方案1:使用Node服务部署(推荐)
删除build脚本中的next export指令,构建完成后用next start启动Node服务运行项目,Next.js内置服务会自动处理i18n路由逻辑,不带默认locale前缀的路径可直接正常访问,无需额外配置。
方案2:纯静态导出场景适配
如果必须使用next export做纯静态部署,可选择以下任一方式处理:
路径复制法
构建完成后,手动或写脚本将out目录下/en/文件夹内的所有文件复制到out根目录,让根路径下也存在对应页面的静态资源,即可直接访问不带前缀的路径。
部署服务重写配置
在部署服务上添加重写规则,将不带locale前缀的请求内部映射到默认locale的路径,示例Nginx配置如下:
# 匹配所有不以/en/、/ru/开头的请求,内部重写到/en/对应路径 location ~ ^/(?!(en|ru)/)(.*)$ { rewrite ^/(.*)$ /en/$1 last; }
方案3:中间件适配(Next.js 12+版本适用)
在项目根目录新增middleware.js文件,通过中间件对路径做重写处理,示例代码如下:
import { NextResponse } from 'next/server' export function middleware(request) { const { pathname } = request.nextUrl // 排除静态资源、接口等不需要处理的路径 if (pathname.startsWith('/_next/') || pathname.startsWith('/api/') || pathname === '/favicon.ico') { return NextResponse.next() } // 检查路径是否已经包含locale前缀 const hasLocale = /^\/(en|ru)(\/|$)/.test(pathname) if (!hasLocale) { // 内部重写到默认locale对应的路径 return NextResponse.rewrite(new URL(`/en${pathname}`, request.url)) } return NextResponse.next() }
内容的提问来源于stack exchange,提问作者whiskeyhoney
相关产品推荐
相关产品推荐

