如何在使用App Router的 Next.js 应用程序中实现国际化
通过国际化(i18n)使您的 React 应用更加易用,拓展新的市场。
随着世界日益全球化,网页开发者构建能够满足来自不同国家和文化用户需求的应用程序变得越来越重要。实现这一目标的关键方法之一是国际化(i18n),它允许您将应用程序适配不同的语言、货币和日期格式。
在本文中,我们将探讨如何为您的 React Next.js 应用添加国际化功能,并实现服务器端渲染。 TL;DR: 查看完整示例。
本指南适用于使用 App Router 的 Next.js 应用程序。
如果您正在使用 Pages Router,请参阅此指南。
步骤 1: 安装一个 i18n 库
要在您的 Next.js 应用程序中实现国际化,首先我们将选择一个 i18n 库。有几个流行的库,包括 next-intl。然而,在本示例中,我们将使用 TacoTranslate。
TacoTranslate 使用前沿的 AI 技术自动将您的字符串翻译成任何语言,免去了您管理 JSON 文件的繁琐工作。
让我们在终端使用 npm 来安装它:
npm install tacotranslate
步骤 2: 创建一个免费的 TacoTranslate 账户
现在您已经安装了模块,是时候创建您的 TacoTranslate 账户、翻译项目以及相关的 API 密钥了。在这里创建账户。 这完全免费,且 无需添加信用卡。
在 TacoTranslate 应用界面中,创建一个项目,并导航到其 API 密钥标签页。创建一个 read
密钥和一个 read/write
密钥。我们将把它们保存为环境变量。 read
密钥称为 public
,而 read/write
密钥称为 secret
。例如,您可以将它们添加到项目根目录下的 .env
文件中。
TACOTRANSLATE_PUBLIC_API_KEY=123456
TACOTRANSLATE_SECRET_API_KEY=789010
请务必绝不泄露秘密 read/write
API 密钥到客户端生产环境。
我们还将添加另外两个环境变量:TACOTRANSLATE_DEFAULT_LOCALE
和 TACOTRANSLATE_ORIGIN
。
TACOTRANSLATE_DEFAULT_LOCALE
:默认的后备语言代码。在此示例中,我们将其设置为en
,代表英语。TACOTRANSLATE_ORIGIN
:“文件夹”,用于存储您的字符串,例如您的网站 URL。在此处阅读有关 origin 的更多信息。
TACOTRANSLATE_DEFAULT_LOCALE=en
TACOTRANSLATE_ORIGIN=your-website-url.com
步骤 3: 设置 TacoTranslate
要将 TacoTranslate 集成到您的应用程序中,您需要使用之前的 API 密钥创建一个客户端。例如,创建一个名为 /tacotranslate-client.js
的文件。
const {default: createTacoTranslateClient} = require('tacotranslate');
const tacoTranslate = createTacoTranslateClient({
apiKey:
process.env.TACOTRANSLATE_SECRET_API_KEY ??
process.env.TACOTRANSLATE_PUBLIC_API_KEY ??
process.env.TACOTRANSLATE_API_KEY,
projectLocale:
process.env.TACOTRANSLATE_IS_PRODUCTION === 'true'
? process.env.TACOTRANSLATE_PROJECT_LOCALE
: undefined,
});
module.exports = tacoTranslate;
我们将很快自动定义 TACOTRANSLATE_API_KEY
和 TACOTRANSLATE_PROJECT_LOCALE
。
在一个单独的文件中创建客户端使其以后更容易再次使用。getLocales
只是一个带有一些内置错误处理的实用函数。现在,创建一个名为 /app/[locale]/tacotranslate.tsx
的文件,我们将在这里实现 TacoTranslate
提供程序。
'use client';
import React, {type ReactNode} from 'react';
import {
type TranslationContextProperties,
TacoTranslate as ImportedTacoTranslate,
} from 'tacotranslate/react';
import tacoTranslateClient from '@/tacotranslate-client';
export default function TacoTranslate({
locale,
origin,
localizations,
children,
}: TranslationContextProperties & {
readonly children: ReactNode;
}) {
return (
<ImportedTacoTranslate
client={tacoTranslateClient}
locale={locale}
origin={origin}
localizations={localizations}
>
{children}
</ImportedTacoTranslate>
);
}
请注意 'use client';
表明这是一个客户端组件。
上下文提供程序现在准备就绪,创建一个名为 /app/[locale]/layout.tsx
的文件,这是我们应用程序中的根布局。请注意,此路径有一个使用 Dynamic Routes的文件夹,其中 [locale]
是 dynamic 参数。
import React, {type ReactNode} from 'react';
import {type Locale, isRightToLeftLocaleCode} from 'tacotranslate';
import './global.css';
import tacoTranslateClient from '@/tacotranslate-client';
import TacoTranslate from './tacotranslate';
export async function generateStaticParams() {
const locales = await tacoTranslateClient.getLocales();
return locales.map((locale) => ({locale}));
}
type RootLayoutParameters = {
readonly params: Promise<{locale: Locale}>;
readonly children: ReactNode;
};
export default async function RootLayout({params, children}: RootLayoutParameters) {
const {locale} = await params;
const origin = process.env.TACOTRANSLATE_ORIGIN;
const localizations = await tacoTranslateClient.getLocalizations({
locale,
origins: [origin /* , other origins to fetch */],
});
return (
<html lang={locale} dir={isRightToLeftLocaleCode(locale) ? 'rtl' : 'ltr'}>
<body>
<TacoTranslate
locale={locale}
origin={origin}
localizations={localizations}
>
{children}
</TacoTranslate>
</body>
</html>
);
}
这里首先要注意的是,我们使用了 Dynamic Route
参数 [locale]
来获取该语言的翻译内容。此外,generateStaticParams
确保了所有你为项目激活的语言代码都被预渲染。
现在,让我们构建我们的第一个页面!创建一个名为 /app/[locale]/page.tsx
的文件。
import React from 'react';
import {Translate} from 'tacotranslate/react';
export const revalidate = 60;
export default async function Page() {
return (
<Translate string="Hello, world!" />
);
}
注意 revalidate
变量,它告诉 Next.js 在 60 秒后重新构建页面,并保持你的翻译内容是最新的。
步骤 4: 实现服务器端渲染
TacoTranslate 支持服务器端渲染。这大大提升了用户体验,因为它能够立即显示翻译后的内容,而不是先闪现未翻译的内容。此外,我们还可以跳过客户端的网络请求,因为我们已经拥有用户正在浏览页面所需的翻译内容。
要设置服务器端渲染,请创建或修改 /next.config.js
:
const withTacoTranslate = require('tacotranslate/next/config').default;
const tacoTranslateClient = require('./tacotranslate-client');
module.exports = async () => {
const config = await withTacoTranslate(
{},
{
client: tacoTranslateClient,
isProduction:
process.env.TACOTRANSLATE_ENV === 'production' ||
process.env.VERCEL_ENV === 'production' ||
(!(process.env.TACOTRANSLATE_ENV || process.env.VERCEL_ENV) &&
process.env.NODE_ENV === 'production'),
}
);
// NOTE: Remove i18n from config when using the app router
return {...config, i18n: undefined};
};
修改 isProduction
检查以适合您的设置。如果 true
,TacoTranslate 将显示公有 API 密钥。如果我们在本地、测试或暂存环境 (isProduction
is false
) 中,我们将使用密钥 read/write
API 密钥来确保发送新字符串进行翻译。
为了确保路由和重定向按预期工作,我们需要创建一个名为 /middleware.ts
的文件。使用 Middleware,我们可以将用户重定向到以其首选语言呈现的页面。
import {type NextRequest} from 'next/server';
import {middleware as tacoTranslateMiddleware} from 'tacotranslate/next';
import tacoTranslate from '@/tacotranslate-client';
export const config = {
matcher: ['/((?!api|_next|favicon.ico).*)'],
};
export async function middleware(request: NextRequest) {
return tacoTranslateMiddleware(tacoTranslate, request);
}
确保按照Next.js 中间件文档设置 matcher
。
在客户端,您可以更改 locale
cookie 来改变用户的首选语言。请参阅 完整示例代码,了解如何操作的思路!
步骤 5: 部署并测试!
我们完成了!当你在 Translate
组件中添加任何字符串时,你的 React 应用将会自动翻译。请注意,只有拥有 read/write
权限的 API 密钥环境才能创建新的待翻译字符串。我们建议你建立一个封闭且安全的预发布环境,在那里使用这样的 API 密钥测试你的生产应用,并在上线前添加新的字符串。这样可以防止任何人窃取你的秘密 API 密钥,并避免通过添加无关字符串而使你的翻译项目膨胀。
务必查看我们GitHub主页上的完整示例。在那里,您还会找到如何使用 Pages Router 实现此功能的示例!如果遇到任何问题,欢迎随时联系我们,我们将非常乐意提供帮助。
TacoTranslate 让您能够快速自动地将 React 应用程序本地化到任意语言,立即开始使用!