如何让Next.js i18n路由始终在URL中显示默认区域en?
Next.js i18n 强制显示默认语言URL前缀的实现方案
Next.js 官方i18n路由默认会把默认语言映射到根路径(比如/对应en),没有直接的配置项让默认语言强制显示前缀。不过可以通过以下两种方式实现需求:
方法一:用中间件(推荐,Next.js 12+)
中间件可以在请求到达页面之前统一处理路由重定向,是最简洁的方案:
- 在项目根目录创建
middleware.ts(或middleware.js)文件,写入以下逻辑:
import { NextResponse } from 'next/server' import type { NextRequest } from 'next/server' const DEFAULT_LANG = 'en' const SUPPORTED_LANGS = ['en', 'th'] export function middleware(request: NextRequest) { const pathname = request.nextUrl.pathname // 跳过静态资源、API、Next.js内部路径,避免影响正常功能 if (pathname.startsWith('/_next/') || pathname.startsWith('/api/') || pathname.match(/\.(png|jpg|jpeg|gif|ico|svg|css|js)$/)) { return NextResponse.next() } // 检查路径是否已包含语言前缀 const hasLangPrefix = SUPPORTED_LANGS.some(lang => pathname.startsWith(`/${lang}/`) || pathname === `/${lang}`) if (!hasLangPrefix) { // 重定向到带默认语言前缀的路径 const redirectPath = `/${DEFAULT_LANG}${pathname || '/'}` const redirectUrl = new URL(redirectPath, request.url) return NextResponse.redirect(redirectUrl) } } // 让中间件匹配所有路径 export const config = { matcher: '/:path*', }
- 调整
next.config.js的i18n配置,确保默认语言为en,可选禁用自动语言检测避免冲突:
/** @type {import('next').NextConfig} */ const nextConfig = { i18n: { locales: ['en', 'th'], defaultLocale: 'en', localeDetection: false, // 禁用浏览器语言自动检测,防止和自定义重定向冲突 }, } module.exports = nextConfig
方法二:页面组件内手动处理重定向
如果项目用静态生成或服务端渲染,也可以在页面里加重定向逻辑:
比如根页面pages/index.tsx:
import { GetServerSideProps } from 'next' import { useRouter } from 'next/router' export default function Home() { const router = useRouter() // 客户端兜底,防止中间件未覆盖的情况 if (router.pathname === '/' && router.locale === 'en') { router.push('/en') return null } return <div>首页内容</div> } export const getServerSideProps: GetServerSideProps = async ({ req, res }) => { // 服务端直接重定向根路径到/en if (req.url === '/') { res.writeHead(302, { Location: '/en' }) res.end() return { props: {} } } return { props: {} } }
其他页面(比如pages/about.tsx)同理,访问/about时重定向到/en/about。
注意事项
- 用中间件时一定要排除静态资源和API路径,不然会导致图片、样式、接口无法正常访问
- 禁用
localeDetection后,用户切换语言需要通过你自己实现的语言切换组件来完成 - 测试前清一下浏览器缓存,避免旧的路由缓存干扰结果
内容的提问来源于stack exchange,提问作者Kaung Khant Zaw
相关产品推荐
相关产品推荐

