Недавно я работал над увлекательным проектом, который включал создание веб-сайта с возможностью переключения языков для привлечения более широкой аудитории. Это позволило мне лучше понять концепцию “локализации”, которая обычно подразумевает адаптацию контента, чтобы он был актуальным, доступным и понятным для пользователей на разных языках и в различных регионах.
Локализация не только о переводе слов, это создание опыта, который заставляет пользователей чувствовать себя как дома, независимо от их языка. Например, глобальные платформы, такие как Amazon, делают переключение языков настолько плавным, что это кажется почти волшебством. Помимо улучшения пользовательского опыта, эта функция играет ключевую роль в развитии бизнеса за счет привлечения более широкой аудитории и укрепления связей с клиентами по всему миру.
Содержание
Что такое i18n и зачем его использовать?
I18n, сокращение от интернационализации, означает, что приложение поддерживает несколько языков. “i18n” происходит от того факта, что между первой буквой “i” и последней “n” в слове “internationalization” находится 18 букв. Это все о том, чтобы сделать ваше приложение адаптивным для глобальной аудитории, обеспечивая перевод текста, форматирование дат и чисел, управление валютами и соблюдение региональных конвенций.
Активация интернационализации делает ваше приложение не просто инструментом, а включающей платформой, которая непосредственно общается с предпочтениями и культурой пользователя.
Давайте приступим
Мы создадим очень простое демо-многоязычное веб-приложение с функцией переключения темного режима, чтобы продемонстрировать, как достичь этой концепции.
Предварительные требования
-
Базовые знания React – Вы должны понимать, как создавать компоненты, управлять состоянием и использовать хуки, такие как
useState
иuseEffect
. Если вы новичок в React, я рекомендую начать с официальной документации по React для устойчивого фундамента. -
Знакомство с концепциями интернационализации – Знание основ интернационализации (i18n) и ее важности даст вам контекст для проекта. Ранние разделы этой статьи охватывают основы.
-
Технология Tailwind CSS – Мы будем использовать Tailwind CSS для стилизации. Это фреймворк CSS первой утилиты, который поможет вам создавать современные, отзывчивые дизайны, не покидая HTML. Если вы не знакомы с ним, ознакомьтесь с документацией Tailwind.
-
Node.js – Убедитесь, что Node.js установлен на вашей системе для обработки зависимостей. Вы можете скачать последнюю версию с Node.js.
-
Менеджер пакетов – Для управления зависимостями проекта требуется использовать npm (включен в Node.js) или yarn
Инструменты, которые мы будем использовать
-
Редактор кода
-
Библиотека локализации: react-i18next
-
Библиотека иконок: hero-icons
Шаг 1: Как настроить проект
Инициализация проекта
Используйте Vite для быстрой настройки:
npm create vite@latest multilingual-demo
Следуйте инструкциям, которые появятся в вашем терминале, выбрав React и TypeScript для разработки, как показано на изображении ниже:
Установка зависимостей
Запустите следующие команды в вашем терминале, чтобы установить необходимые зависимости для этого проекта:
npm install i18next react-i18next i18next-browser-languagedetector i18next-http-backend heroicons
npm install tailwindcss postcss autoprefixer
npx tailwindcss init
Настройка TailwindCSS
Обновите файл tailwind.config.ts
:
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./src/**/*.{js,jsx,ts,tsx}"],
darkMode: "class", // Для функционала темного режима
theme: {
container: {
center: true,
padding: "1.25rem",
screens: {
sm: "1200px",
},
},
extend: {},
},
plugins: [],
};
Добавьте TailwindCSS в src/index.css
:
@tailwind base;
@tailwind components;
@tailwind utilities;
Шаг 2: Как настроить международную локализацию с i18next
Инициализация i18next
Создайте файл i18n.tsx
в папке src
и настройте i18next:
import i18next from "i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import { initReactI18next } from "react-i18next";
import Backend from "i18next-http-backend";
i18next.use(LanguageDetector).use(initReactI18next).use(Backend).init({
returnObjects: true,
fallbackLng: "en", // Язык, на который нужно переключиться, если выбранный не настроен
debug: true, // Для отображения ошибок
// lng: "en", // Язык по умолчанию - английский
});
Давайте кратко рассмотрим содержимое этого файла, так как он играет ключевую роль в обеспечении функциональности перевода. Этот файл отвечает за настройку основы процесса перевода и гарантирует плавную работу функции переключения языка в вашем приложении.
-
i18next
: Основная библиотека внутренней локализации, которую мы используем для перевода. -
LanguageDetector
: Помогает автоматически определить предпочитаемый язык пользователя на основе настроек браузера. -
initReactI18next
: Отвечает за интеграцию плагинаi18next
с React и предоставляет хуки, такие как хукuseTranslation
и другие утилиты. -
Backend
: Динамически извлекает данные перевода из внешнего источника. В данном случае мы будем использовать файлы JSON.
Импортируйте этот файл в файл main.tsx
:
//main.tsx
import React, { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import "./index.css";
import App from "./App.tsx";
import "./i18n.tsx"; //Импортируйте здесь
createRoot(document.getElementById("root")!).render(
<StrictMode>
<React.Suspense fallback="loading">
<App />
</React.Suspense>
</StrictMode>
);
Создание файлов перевода
В каталоге public/locales
создайте подпапки для каждого языка (например, en
, fr
) и включите файлы translation.json
:
en/translation.json
{
"greeting": "Welcome to the Language Playground",
"detail": {
"line1": "Did you know that over 7,000 languages are spoken worldwide?",
"line2": "This Playground demonstrates how web applications can support users in multiple languages, making them accessible and inclusive to people from different backgrounds."
}
}
fr/translation.json
{
"greeting": "Bienvenue sur le terrain de jeu linguistique",
"detail": {
"line1": "Saviez-vous que plus de 7 000 langues sont parlées dans le monde ?",
"line2": "Ce terrain de jeu démontre comment les applications web peuvent prendre en charge les utilisateurs dans plusieurs langues, les rendant accessibles et inclusives aux personnes de différents horizons."
}
}
Здесь вы можете добавить столько языков с их файлами перевода, которые будут предоставлены i18next
. Обратите внимание, что ключи в файлах JSON совпадают с теми, которые будут использоваться в качестве ссылок при их отображении на веб-сайте.
Шаг 3: Как создать компоненты
Создайте папку components
в каталоге src
и добавьте следующие компоненты:
Выбор языка
Создайте компонент LanguageSelector
– содержит элемент select
, чтобы помочь пользователям динамически переключать языки:
import { useEffect, useState } from "react";
import i18next from "i18next";
import { useTranslation } from "react-i18next";
type languageOption = { language: string; code: string };
const languageOptions: languageOption[] = [
{
language: "English",
code: "en",
},
{ language: "French", code: "fr" },
{ language: "German", code: "de" },
{ language: "Spanish", code: "es" },
{ language: "Arabic", code: "ar" },
{ language: "Yoruba", code: "yo" },
];
const LanguageSelector = () => {
// Установите начальный язык из обнаруженного или заданного языка по умолчанию от i18next
const [language, setLanguage] = useState(i18next.language);
const { i18n } = useTranslation();
const handleLanguageChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
const selectedLanguage = e.target.value;
setLanguage(selectedLanguage);
i18next.changeLanguage(selectedLanguage); // Обновить язык в i18next
};
useEffect(() => {
document.body.dir = i18n.dir(); // устанавливает направление текста на ltr или rtl
}, [i18n, i18n.language]);
return (
<select
id="language"
value={language}
onChange={handleLanguageChange}
className="p-2 border border-gray-300 rounded-md shadow-sm focus:border-indigo-500 focus:ring focus:ring-indigo-200 focus:ring-opacity-50
dark:bg-gray-800 dark:border-gray-600 dark:text-gray-200 dark:focus:border-indigo-400 dark:focus:ring-indigo-700 dark:focus:ring-opacity-50"
>
{languageOptions.map(({ language, code }, key) => (
<option value={code} key={key}>
{language}
</option>
))}
</select>
);
};
export default LanguageSelector;
-
Инициализируйте язык с языком, обнаруженным
i18next
, или с заданным языком по умолчанию. -
Хук
useTranslation
предоставляет экземплярi18n
изi18next
для взаимодействия с настройками интернационализации. -
Функция
handleLanguageChange
будет использоваться для обновления языка, выбранного пользователем. Она срабатывает, когда пользователь выбирает новый язык из выпадающего меню.
Реализация направления текста
Атрибут dir
в HTML является важной функцией для обеспечения доступности и инклюзивности в веб-приложениях, особенно при работе с языками, отличающимися направлением текста. Например:
-
Слева направо (LTR): Большинство языков, включая английский, французский и испанский, следуют этому направлению.
Справа налево (RTL): Языки, такие как арабский и иврит, требуют переключения выравнивания текста и макета для сохранения читаемости и культурного контекста.
Для достижения этого в нашем приложении мы устанавливаем document.body.dir
в значение dir
из i18n
, слушая изменения в выборе языка с помощью хука useEffect
Переключатель темной темы
Создайте компонент DarkModeToggle
, чтобы переключаться между светлым и темным режимом по предпочтению пользователя.
import { useEffect, useState } from "react";
import { SunIcon, MoonIcon } from "@heroicons/react/solid";
const DarkModeToggle = () => {
const [darkMode, setDarkMode] = useState(false);
useEffect(() => {
// Проверка локального хранилища или предпочтений системы при первой загрузке
const isDark =
localStorage.getItem("theme") === "dark" ||
(!localStorage.getItem("theme") &&
window.matchMedia("(prefers-color-scheme: dark)").matches);
setDarkMode(isDark);
document.documentElement.classList.toggle("dark", isDark);
}, []);
const toggleDarkMode = () => {
setDarkMode(!darkMode);
document.documentElement.classList.toggle("dark", !darkMode);
localStorage.setItem("theme", !darkMode ? "dark" : "light");
};
return (
<button
aria-label="Toggle dark mode"
onClick={toggleDarkMode}
className="p-1 rounded"
>
{darkMode ? (
<SunIcon
className="w-6 h-6 text-yellow-500 "
onClick={toggleDarkMode}
/>
) : (
<MoonIcon className="w-6 h-6 text-gray-900 " onClick={toggleDarkMode} />
)}
</button>
);
};
export default DarkModeToggle;
Компонент заголовка
Компонент Header
служит родительским компонентом для компонентов DarkModeToggle
и languageSelector
.
import DarkModeToggle from "./DarkModeToggle";
import LanguageSelector from "./LanguageSelector";
const Header = () => {
return (
<header className="container flex justify-between">
<DarkModeToggle />
<LanguageSelector />
</header>
);
};
export default Header;
Шаг 4: Главный компонент приложения
В файле src/app
включите следующее:
import { useTranslation } from "react-i18next";
import Header from "./components/Header";
const App = () => {
const { t } = useTranslation();
const line1 = t("detail.line1");
const line2 = t("detail.line2");
return (
<div className="h-[100vh] bg-white text-black dark:bg-gray-900 dark:text-white py-8">
<Header />
<div className="container text-center max-w-2xl mt-28">
<h1 className="text-4xl font-bold">{t("greeting")}</h1>
<p className="mt-8">{line1}</p>
<p className="mt-2">{line2}</p>
</div>
</div>
);
};
export default App;
-
Hook
useTranslation
изreact-i18next
предоставляет функциюt
, которая используется для получения переведенного текста. -
Она извлекает переведенную строку на основе ключа из ваших файлов перевода (например,
en.json
,fr.json
).
Следуя этим шагам, ваше приложение теперь должно быть полностью функциональным с интегрированным переводом. Вот как выглядит окончательный результат нашего приложения:
Ознакомьтесь с живым демо и исходным кодом на GitHub
Заключение
Создание веб-сайтов, которые предоставляют пользователям гибкость выбора предпочитаемого языка, является не только техническим достижением, но и шагом к созданию более инклюзивного и приветливого веба.
Комбинируя интернационализацию (i18n) с инструментами, такими как React-i18next, и стилизацию с помощью Tailwind CSS, вы можете создавать приложения, которые гибкие, удобные для пользователя и доступные для глобальной аудитории.
В этом проекте мы рассмотрели настройку i18n, добавление переключателя языка и включение “темного режима” для улучшения удобства использования.
Ссылки
Source:
https://www.freecodecamp.org/news/build-multilingual-apps-with-i18n-in-react/