共计 3807 个字符,预计需要花费 10 分钟才能阅读完成。
目录
Next.js 作为一个流行的 React 框架,为构建多语言支持的应用程序提供了强大的支持。本指南将引导你完成在 Next.js 项目中实现国际化 (i18n) 的步骤。我们将涵盖路由设置、本地化处理和翻译内容管理。
理解国际化术语
区域设置(Locale)
区域设置是一组语言和格式化偏好的标识符。它包括用户的首选语言,也可能指示他们的地理区域。例如:
- ‘en-US’:美国使用的英语
- ‘nl-NL’:荷兰使用的荷兰语
- ‘en’:没有特定区域的英语
设置 Next.js 国际化
创建新的 Next.js 应用
如果你还没有,使用以下命令创建一个新的 Next.js 项目:
npm install @formatjs/intl-localematcher negotiator
实现基于区域设置的路由
Next.js 允许你通过子路径 (/fr/products)
或域名 (my-site.fr/products)
来国际化路由。这些信息使你能够在中间件中根据用户的首选区域设置重定向用户。
在 src/
目录下创建 middleware.ts
文件:
// middleware.ts
import {match} from '@formatjs/intl-localematcher'
import Negotiator from 'negotiator'
import {NextRequest, NextResponse} from 'next/server'
let defaultLocale = 'en'
let locales = ['cn', 'de', 'en']
// 获取首选区域设置,类似上面或使用库
function getLocale(request: NextRequest) {const acceptedLanguage = request.headers.get('accept-language') ?? undefined
let headers = {'accept-language': acceptedLanguage}
let languages = new Negotiator({headers}).languages()
return match(languages, locales, defaultLocale) // -> 'en-US'
}
export function middleware(request: NextRequest) {
// 检查路径中是否有任何支持的区域设置
const pathname = request.nextUrl.pathname
const pathnameIsMissingLocale = locales.every((locale) => !pathname.startsWith(`/${locale}/`) && pathname !== `/${locale}`
)
// 如果没有区域设置则重定向
if (pathnameIsMissingLocale) {const locale = getLocale(request)
// 例如,传入的请求是 /products
// 新的 URL 现在是 /en-US/products
return NextResponse.redirect(new URL(`/${locale}/${pathname}`, request.url))
}
}
export const config = {
matcher: [// 跳过所有内部路径 (_next, assets, api)
'/((?!api|assets|.*..*|_next).*)',
// 可选:只在根 (/) URL 上运行
// '/'
],
}
组织文件以进行基于区域设置的处理
为了使 Next.js 能够在路由中动态管理不同的区域设置,将所有特殊文件嵌套在 app/[lang]
中。
例如:
// app/[lang]/page.tsx
export default async function Page({params: { lang} }) {return ...}
实现本地化
本地化涉及根据用户的首选区域设置调整显示的内容。这可以通过为每种支持的语言维护单独的字典来实现。
创建字典
例如,我们考虑 Next.js 主页的英语、荷兰语和中文翻译。
app/[lang]/dictionaries
dictionaries/en.json
:
{
"get_started": "Get started by editing",
"doc": "Find in-depth information about Next.js features and API.",
"learn": "Learn about Next.js in an interactive course with quizzes!",
"template": "Explore the Next.js 13 playground.",
"deploy": "Instantly deploy your Next.js site to a shareable URL with Vercel."
}
dictionaries/de.json:
{
"get_started": "Beginnen Sie, indem Sie bearbeiten",
"doc": "Finden Sie ausführliche Informationen zu den Funktionen und der API von Next.js.",
"learn": "Erfahren Sie mehr über Next.js in einem interaktiven Kurs mit Quizfragen!",
"template": "Erkunden Sie den Next.js 13-Spielplatz.",
"deploy": "Bereiten Sie Ihre Next.js-Website sofort für die Bereitstellung auf einer gemeinsam nutzbaren URL mit Vercel vor."
}
dictionaries/cn.json:
{
"get_started": "通过编辑开始",
"doc": "查找关于 Next.js 功能和 API 的深入信息。",
"learn": "通过互动课程学习 Next.js,包括测验!",
"template": "探索 Next.js 13 的示范环境。",
"deploy": "使用 Vercel 立即部署您的 Next.js 网站到可共享的 URL。"
}
加载翻译
创建一个 getDictionary 函数来加载请求的区域设置的翻译。
import 'server-only'
export type Locale = keyof typeof dictionaries
const dictionaries = {en: () => import('./dictionaries/en.json').then((module) => module.default),
de: () => import('./dictionaries/de.json').then((module) => module.default),
cn: () => import('./dictionaries/cn.json').then((module) => module.default),
}
export const getDictionary = async (locale: Locale) => dictionaries[locale]()
在组件中使用翻译
现在你可以在布局或页面中获取字典以显示翻译后的内容。
import SwitchLang from '@/components/SwitchLang/SwitchLang'
import Image from 'next/image'
import {Locale, getDictionary} from './dictionaries'
import styles from './page.module.css'
type Props = {
params: {lang: Locale}
}
export default async function Home({params: { lang} }: Props) {const intl = await getDictionary(lang)
return (
{intl.get_started}
src/app/page.tsx
{/* ... 其余代码 ... */}
{/* ... 其余代码 ... */}
Docs ->
{intl.doc}
{/* ... 其他卡片 ... */}
)
}
为多个区域设置进行静态生成
要为一组区域设置生成静态路由,在任何页面或布局中使用 generateStaticParams。这可以全局设置,例如在根布局中:
// app/[lang]/layout.ts
export async function generateStaticParams() {return [{ lang: 'en'}, {lang: 'de'}, {lang: 'cn'}]
}
export default function Root({children, params}) {
return ({children}
)
}
结语
在 Next.js 中实现国际化为来自不同语言背景的用户提供了无缝体验。通过调整路由,你可以为全球用户创建更加包容和易于访问的应用程序。
如需完整的源代码,包括所有文件和依赖关系,请访问 GitHub 代码库。请随时探索、fork 或克隆该仓库,以深入了解该项目。