如何在使用 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 應用程式的 UI 中,建立一個專案,然後前往其 API keys 分頁。建立一個 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。 在此閱讀有關 origins 的更多資訊。
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]
是動態參數。
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 應用程式現在將會自動被翻譯。請注意,只有在 API 金鑰具有 read/write
權限的環境中,才能建立新的要翻譯的字串。我們建議設置一個封閉且安全的測試(staging)環境,在那裡使用具有此類權限的 API 金鑰測試你的生產應用程式,並在上線前新增字串。這將防止任何人任何人竊取你的秘密 API 金鑰,並可能透過新增無關的字串讓你的翻譯專案膨脹。
Be sure to check out the complete example over at our GitHub profile. There, you’ll also find an example of how to do this using the Pages Router! If you encounter any problems, feel free to reach out, and we’ll be more than happy to help.
TacoTranslate lets you automatically localize your React applications quickly to and from over 75 languages. Get started today!