Как реализовать интернационализацию в приложении Next.js, использующем App Router
Сделайте ваше приложение на React более доступным и выйдите на новые рынки с помощью интернационализации (i18n).
По мере глобализации мира всё важнее для веб-разработчиков создавать приложения, которые могут удовлетворять потребности пользователей из разных стран и культур. Одним из ключевых способов добиться этого является интернационализация (i18n), которая позволяет адаптировать ваше приложение к различным языкам, валютам и форматам даты.
В этой статье мы рассмотрим, как добавить интернационализацию в ваше React Next.js приложение с серверной отрисовкой. TL;DR: См. полный пример здесь.
Это руководство предназначено для приложений Next.js, использующих App Router.
Если вы используете Pages Router, ознакомьтесь с этим руководством.
Шаг 1: Установите библиотеку i18n
Чтобы реализовать интернационализацию в вашем приложении Next.js, сначала выберем библиотеку i18n. Существует несколько популярных библиотек, включая next-intl. В этом примере, однако, мы будем использовать TacoTranslate.
TacoTranslate автоматически переводит ваши строки на любой язык с помощью передовых технологий ИИ и освобождает вас от утомительного управления 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 вашего сайта. Узнайте больше об 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
, корневой layout в нашем приложении. Обратите внимание, что этот путь содержит папку, использующую 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);
}
Убедитесь, что вы настроили matcher
в соответствии с документацией Next.js по Middleware.
На стороне клиента вы можете изменить cookie locale
, чтобы изменить предпочитаемый язык пользователя. Посмотрите полный пример кода, чтобы узнать, как это сделать!
Шаг 5: Разверните и протестируйте!
Мы закончили! Ваше React‑приложение теперь будет автоматически переводиться, когда вы добавите любые строки в компонент Translate
. Обратите внимание, что только окружения с разрешениями read/write
на API‑ключ смогут создавать новые строки для перевода. Мы рекомендуем иметь закрытое и защищённое staging‑окружение, где вы сможете протестировать ваше production‑приложение с таким 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!