Как реализовать интернационализацию в приложении 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
To integrate TacoTranslate with your application, you’ll need to create a client using the API keys from earlier. For example, create a file named /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-ключа, а также потенциальное разрастание вашего проекта перевода за счёт добавления новых, не связанных строк.
Обязательно ознакомьтесь с полным примером в нашем профиле на GitHub. Там вы также найдете пример того, как это сделать с использованием Pages Router ! Если у вас возникнут какие-либо проблемы, не стесняйтесь связаться с нами, и мы будем более чем рады помочь.
TacoTranslate позволяет вам автоматически локализовать ваши React-приложения быстро на любой язык и с любого языка. Начните сегодня!