Next.js v13路由中如何设置可选locale参数?
在Next.js 13中实现带可选locale参数的路由
针对你需要的/[locale?]/lesson/[lesson](lesson必填、locale可选,默认en-US)路由需求,有几种可行的实现方式,下面是具体方案:
方案1:创建两组路由共享组件(简单直接)
Next.js不允许在路由中间段直接使用可选参数,但可以通过创建带locale和不带locale的两组路由,复用同一个业务组件来实现需求:
构建路由结构:
app/ ├── [locale]/ │ └── lesson/ │ └── [lesson]/ │ └── page.tsx # 核心业务组件 └── lesson/ └── [lesson]/ └── page.tsx # 复用核心组件,默认传入en-US实现不带locale的页面组件:
// app/lesson/[lesson]/page.tsx import LessonPage from '../../[locale]/lesson/[lesson]/page'; export default function DefaultLocaleLesson({ params }: { params: { lesson: string } }) { // 直接复用带locale的组件,传入默认locale值 return <LessonPage params={{ locale: 'en-US', lesson: params.lesson }} />; }核心业务组件(
app/[locale]/lesson/[lesson]/page.tsx):export default function LessonPage({ params }: { params: { locale: string; lesson: string } }) { return ( <div> <h1>Lesson {params.lesson}</h1> <p>当前语言:{params.locale}</p> </div> ); }
这种方式无需复杂配置,适合小型项目,用户访问/lesson/123会自动使用en-US,访问/zh-CN/lesson/123则使用对应locale。
方案2:结合Middleware重写路径(避免重复代码)
如果不想维护两组路由文件,可以用Middleware将不带locale的请求内部重写到带默认locale的路由,地址栏不会发生变化:
构建单一路由结构:
app/ └── [locale]/ └── lesson/ └── [lesson]/ └── page.tsx编写Middleware(
middleware.ts):import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; // 支持的locale列表 const supportedLocales = ['en-US', 'zh-CN']; const defaultLocale = 'en-US'; export function middleware(request: NextRequest) { const pathname = request.nextUrl.pathname; // 跳过静态资源和API路由 if (pathname.startsWith('/_next/') || pathname.startsWith('/api/')) { return NextResponse.next(); } // 检查路径是否已包含有效locale const hasValidLocale = supportedLocales.some(locale => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}` ); if (hasValidLocale) { return NextResponse.next(); } // 处理lesson路径:重写到带默认locale的路由(地址栏不变) if (pathname.startsWith('/lesson/')) { return NextResponse.rewrite( new URL(`/${defaultLocale}${pathname}`, request.url) ); } // 其他路径:重定向到带默认locale的路由(地址栏会更新) return NextResponse.redirect( new URL(`/${defaultLocale}${pathname}`, request.url) ); } // 匹配所有需要处理的路径 export const config = { matcher: ['/((?!favicon.ico).*)'], };核心组件无需修改,依然可以通过
params.locale获取当前语言(不管是用户直接访问带locale的路径,还是Middleware重写过来的请求)。
方案3:使用Next.js内置国际化支持(推荐)
Next.js 13的App Router内置了国际化支持,配置后可以自动处理带/不带locale的路径映射:
在
next.config.js中配置i18n:/** @type {import('next').NextConfig} */ const nextConfig = { i18n: { locales: ['en-US', 'zh-CN'], defaultLocale: 'en-US', localeDetection: false, // 关闭自动检测,用自定义逻辑控制 }, }; module.exports = nextConfig;构建路由结构:
app/ └── [locale]/ └── lesson/ └── [lesson]/ └── page.tsx此时用户访问
/lesson/123会自动映射到en-US的路由,访问/zh-CN/lesson/123则使用对应locale,无需额外编写路由文件或复杂的Middleware逻辑。
内容的提问来源于stack exchange,提问作者srhuevo
相关产品推荐
相关产品推荐

