Как реализовать интернационализацию в приложении 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
Обязательно никогда не раскрывайте секретный ключ API read/write
в клиентских продакшен-средах.
Также мы добавим ещё две переменные окружения: TACOTRANSLATE_DEFAULT_LOCALE
и TACOTRANSLATE_ORIGIN
.
TACOTRANSLATE_DEFAULT_LOCALE
: Код локали по умолчанию для использования в качестве резервного варианта. В этом примере мы установим значениеen
для английского языка.TACOTRANSLATE_ORIGIN
: «Папка», в которой будут храниться ваши строки, например URL вашего сайта. Подробнее о происхождении здесь.
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
), мы будем использовать секретный API-ключ read/write
, чтобы новые строки отправлялись на перевод.
Чтобы обеспечить корректную работу маршрутизации и перенаправления, нам нужно создать файл с именем /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-ключ смогут создавать новые строки для перевода. Мы рекомендуем иметь закрытую и защищённую среду для тестирования, где вы можете проверить ваше продуктивное приложение с таким 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!