Как сделать мультиязнычость сайта?

Для реализации мультиязычности на сайте, используя React, существует несколько подходов. Рассмотрим два наиболее распространенных способа.

1. Использование контекста:
Контекст в React предоставляет возможность передавать данные глубоко внутрь компонентов без необходимости передачи пропсов через каждый промежуточный компонент. Мы можем использовать контекст для хранения текущего выбранного языка и его словаря сообщений.

Создайте файл i18n.js, который будет выглядеть примерно так:

import React from 'react';

const dictionaryEN = {
  greet: 'Hello',
  title: 'Welcome to my website'
};

const dictionaryFR = {
  greet: 'Bonjour',
  title: 'Bienvenue sur mon site web'
};

const dictionaryES = {
  greet: 'Hola',
  title: 'Bienvenido a mi sitio web'
};

export const languages = {
  en: dictionaryEN,
  fr: dictionaryFR,
  es: dictionaryES
};

const LanguageContext = React.createContext();

export default LanguageContext;

Затем создайте компонент LanguageProvider, который будет предоставлять актуальный выбранный язык и словарь сообщений всем дочерним компонентам:

import React, { useState } from 'react';
import LanguageContext, { languages } from './i18n';

const LanguageProvider = ({ children }) => {
  const [language, setLanguage] = useState('en'); // задаем начальный язык по умолчанию

  const changeLanguage = (newLanguage) => {
    setLanguage(newLanguage);
  };

  return (
    <LanguageContext.Provider value={{ language, dictionary: languages[language], changeLanguage }}>
      {children}
    </LanguageContext.Provider>
  );
};

export default LanguageProvider;

Теперь можно использовать компонент LanguageProvider в верхнем уровне вашего приложения и обернуть в него все компоненты, которым требуется доступ к языковым словарям.

Внутри компонентов, которым необходимо получить доступ к словарю сообщений, вы можете воспользоваться хуком useContext и получить набор терминов сообщений для текущего выбранного языка. Например:

import React, { useContext } from 'react';
import LanguageContext from './i18n';

const GreetingComponent = () => {
  const { dictionary } = useContext(LanguageContext);

  return (
    <div>
      <h1>{dictionary.greet}</h1>
      <p>{dictionary.title}</p>
    </div>
  );
};

export default GreetingComponent;

2. Использование библиотеки react-i18next:
Библиотека react-i18next предоставляет более гибкое и мощное решение для реализации мультиязычности. Она предоставляет широкий выбор функций, таких как подстановки переменных, множественные формы и многое другое.

Для начала установите библиотеку:

npm install react-i18next i18next --save

Затем создайте файл i18n.js:

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';

import dictionaryEN from './locales/en.json';
import dictionaryFR from './locales/fr.json';
import dictionaryES from './locales/es.json';

const resources = {
  en: {
    translation: dictionaryEN
  },
  fr: {
    translation: dictionaryFR
  },
  es: {
    translation: dictionaryES
  }
};

i18n
  .use(initReactI18next)
  .init({
    resources,
    lng: 'en', // задаем начальный язык
    fallbackLng: 'en', // в случае, если не найден перевод для выбранного языка, будет использоваться английский язык
    interpolation: {
      escapeValue: false // необходимо, чтобы react-i18next мог обрабатывать HTML-теги в переводах
    }
  });

export default i18n;

Настройте файлы словарей (en.json, fr.json, es.json) в папке locales в соответствии с вашими требованиями. Например, содержимое файла en.json может выглядеть так:

{
  "greet": "Hello",
  "title": "Welcome to my website"
}

Теперь можно использовать компоненты, предоставляемые библиотекой react-i18next, для мультиязычного отображения текста на страницах вашего сайта:

import React from 'react';
import { useTranslation } from 'react-i18next';

const GreetingComponent = () => {
  const { t } = useTranslation();

  return (
    <div>
      <h1>{t('greet')}</h1>
      <p>{t('title')}</p>
    </div>
  );
};

export default GreetingComponent;

Обратите внимание, что в данном примере мы используем хук useTranslation для получения функции t, которая позволяет нам получить переведенную версию текста с помощью ключа из словаря.

В обоих подходах вы можете предоставить пользователю возможность изменять выбранный язык, сохраняя его в локальном хранилище или передавая через URL.