Как реализовать интернационализацию в приложении 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 ключ в клиентской части production-окружения.
Мы также добавим ещё две переменные окружения: 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-ключ смогут создавать новые строки для перевода. Рекомендуется иметь закрытое и защищённое тестовое окружение (staging), где вы можете протестировать ваше производственное приложение с таким API-ключом, добавляя новые строки перед запуском. Это предотвратит кражу вашего секретного API-ключа и потенциальное раздувание вашего проекта перевода за счёт добавления новых, не связанных со смыслом строк.
Обязательно ознакомьтесь с полным примером в нашем профиле на GitHub. Там вы также найдете пример того, как это сделать, используя Pages Router!
Если у вас возникнут какие-либо проблемы, не стесняйтесь обращаться к нам, и мы с радостью поможем.
TacoTranslate позволяет автоматически локализовать ваши React-приложения быстро на любой язык и наоборот. Начните сегодня!