Next.js+i18next国际化配置:英文无前缀/德文带/de前缀
Next.js App Router + i18next 移除英文路径/en前缀方案
需求明确:德文页面路径带/de前缀,英文页面直接使用根路径(移除现有/en前缀)。以下是具体修改步骤和配置:
1. 调整页面目录结构
将原/app/en/下的所有页面组件,直接迁移到/app/根目录;德文页面保留在/app/de/目录中。最终目录结构示例:
/app ├── layout.js # 英文页面根布局 ├── page.js # 英文首页 ├── about │ └── page.js # 英文关于页 └── de ├── layout.js # 德文页面布局 ├── page.js # 德文首页 └── about └── page.js # 德文关于页
2. 修改中间件(middleware.js)
核心调整路由重定向逻辑:移除英文路径的/en前缀,确保德文路径带/de前缀,同时处理语言检测与cookie设置。
修改后的middleware.js代码:
// middleware.js import { NextResponse } from 'next/server' import acceptLanguage from 'accept-language' import { fallbackLng, languages, cookieName } from './app/i18n/settings' acceptLanguage.languages(languages) export const config = { matcher: ['/((?!api|_next/static|_next/image|assets|favicon.ico|sw.js|site.webmanifest).*)'] } export function middleware(req) { let lng // 从cookie读取语言偏好 if (req.cookies.has(cookieName)) lng = acceptLanguage.get(req.cookies.get(cookieName).value) // 从请求头获取语言 if (!lng) lng = acceptLanguage.get(req.headers.get('Accept-Language')) // 默认使用英文 if (!lng) lng = fallbackLng // 重定向带/en前缀的路径到根路径格式 if (req.nextUrl.pathname.startsWith(`/${fallbackLng}`)) { const newPath = req.nextUrl.pathname.replace(`/${fallbackLng}`, '') || '/' return NextResponse.redirect(new URL(newPath, req.url)) } // 给非英文语言的路径添加对应前缀 const isNonFallbackLng = languages.includes(lng) && lng !== fallbackLng if (isNonFallbackLng && !req.nextUrl.pathname.startsWith(`/${lng}`)) { return NextResponse.redirect(new URL(`/${lng}${req.nextUrl.pathname}`, req.url)) } // 从referer获取语言并更新cookie if (req.headers.has('referer')) { const refererUrl = new URL(req.headers.get('referer')) let lngInReferer = languages.find(l => refererUrl.pathname.startsWith(`/${l}`)) // 根路径默认对应英文 if (!lngInReferer && refererUrl.pathname === '/') lngInReferer = fallbackLng const response = NextResponse.next() if (lngInReferer) response.cookies.set(cookieName, lngInReferer) return response } return NextResponse.next() }
3. 页面组件中获取当前语言
根目录的英文页面直接指定语言为en;德文页面从路由参数中读取lng:
英文首页(/app/page.js)
// app/page.js import { useTranslation } from './i18n' export default async function Home() { const { t } = await useTranslation('en') return <h1>{t('home.title')}</h1> }
德文首页(/app/de/page.js)
// app/de/page.js import { useTranslation } from '../i18n' export default async function Home({ params }) { const { t } = await useTranslation(params.lng) return <h1>{t('home.title')}</h1> }
4. 语言切换组件适配
如果有语言切换按钮,跳转逻辑需对应调整:
- 切换到英文时,跳转到不带前缀的根路径
- 切换到德文时,跳转到带/de前缀的路径
示例切换组件:
'use client' import { usePathname } from 'next/navigation' import { useCookies } from 'react-cookie' import { cookieName } from '../app/i18n/settings' export function LanguageSwitcher() { const pathname = usePathname() const [, setCookie] = useCookies([cookieName]) const handleSwitch = (lng) => { let newPath if (lng === 'en') { // 移除/de前缀,回到根路径格式 newPath = pathname.startsWith('/de') ? pathname.replace('/de', '') : '/' } else { // 添加/de前缀 newPath = pathname.startsWith('/de') ? pathname : `/de${pathname}` } setCookie(cookieName, lng) window.location.href = newPath } return ( <div> <button onClick={() => handleSwitch('en')}>English</button> <button onClick={() => handleSwitch('de')}>Deutsch</button> </div> ) }
修改完成后,访问/en/about会自动重定向到/about,/about直接显示英文内容,/de/about显示德文内容,完全符合需求。
内容的提问来源于stack exchange,提问作者Azazot Mowla
相关产品推荐
相关产品推荐

