Словари

Как использовать традиционные шаблоны перевода на основе словарей

Словари — это традиционный способ организовывать переводы во вложенных объектах с парами ключ‑значение. Хотя рекомендуемым подходом являются компоненты <T>, словари могут быть полезны при миграции с других i18n‑библиотек или если вы предпочитаете централизованное хранение переводов.

Рекомендация: Используйте компоненты <T> для новых проектов. Поддержка словарей предназначена прежде всего для миграции и совместимости с существующими процессами перевода.

Переводы словарём vs. перевод компонентов

Паттерн «Dictionary»

// dictionary.ts
export default {
  greetings: {
    hello: 'Привет, мир!',
    welcome: 'Добро пожаловать, {name}!'
  }
};

// Component usage
function MyComponent() {
  const d = useTranslations();
  return <div>{d('greetings.hello')}</div>;
}

Паттерн компонента

// Прямое использование компонента — рекомендуется
function MyComponent() {
  return <T><div>Привет, мир!</div></T>;
}

Баланс плюсов и минусов

Преимущества словаря

  • Централизованное хранение — все переводы в одном месте
  • Отраслевой стандарт — знакомый подход из других i18n‑библиотек
  • Удобен для миграции — легко перенести существующие переводы

Недостатки словаря

  • Сложность — требуется больше настройки и конфигурации
  • Сопровождаемость — отделение контента от места использования усложняет обновления
  • Отлаживаемость — сложнее проследить, к каким компонентам относятся переводы
  • Читаемость — ключи не отражают фактическое содержание

Краткое руководство

Шаг 1: Создайте словарь

Создайте файл словаря в корне проекта или в каталоге src:

dictionary.ts
const dictionary = {
  greetings: {
    hello: 'Привет, мир!',
    welcome: 'Добро пожаловать в наше приложение!'
  },
  navigation: {
    home: 'Главная',
    about: 'О компании',
    contact: 'Связаться с нами'
  }
};

export default dictionary;

Или используйте формат JSON:

dictionary.json
{
  "greetings": {
    "hello": "Привет, мир!",
    "welcome": "Добро пожаловать в наше приложение!",
  },
  "navigation": {
    "home": "Главная", 
    "about": "О нас",
    "contact": "Контакты"
  }
}

Затем передайте его в компонент <GTProvider>:

index.js
import dictionary from "./dictionary.js";
import config from "./gt.config.json";

createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <GTProvider {...config} dictionary={dictionary}>
      <App />
    </GTProvider>
  </StrictMode>
);

Шаг 2: Использование в компонентах

Хук useTranslations позволяет обращаться к записям словаря:

import { useTranslations } from 'gt-react';

function MyComponent() {
  const d = useTranslations();
  
  return (
    <div>
      <h1>{d('greetings.hello')}</h1>
      <p>{d('greetings.welcome')}</p>
    </div>
  );
}

Использование переменных

Добавляйте переменные в элементы словаря, используя синтаксис {variable}:

dictionary.ts
const dictionary = {
  user: {
    greeting: 'Здравствуйте, {name}!',
    itemCount: 'У вас {count} предметов',
    orderTotal: 'Итого: ${amount}'
  }
};
function UserDashboard() {
  const d = useTranslations();
  
  return (
    <div>
      <h1>{d('user.greeting', { name: 'Alice' })}</h1>
      <p>{d('user.itemCount', { count: 5 })}</p>
      <p>{d('user.orderTotal', { amount: 99.99 })}</p>
    </div>
  );
}

Использование префиксов

Ограничьте доступ к словарю определёнными разделами с помощью префиксов:

dictionary.ts
const dictionary = {
  dashboard: {
    header: {
      welcome: 'С возвращением!',
      lastLogin: 'Последний вход: {date}'
    },
    stats: {
      totalUsers: 'Всего пользователей: {count}',
      activeUsers: 'Активных пользователей: {count}'
    }
  }
};
function DashboardHeader() {
  // Префикс ограничивает доступ к 'dashboard.header'
  const d = useTranslations('dashboard.header');
  
  return (
    <header>
      <h1>{d('welcome')}</h1> {/* -> dashboard.header.welcome */}
      <p>{d('lastLogin', { date: 'Сегодня' })}</p> {/* -> dashboard.header.lastLogin */}
    </header>
  );
}

function DashboardStats() {
  // Другой префикс для раздела статистики
  const d = useTranslations('dashboard.stats');
  
  return (
    <div>
      <p>{d('totalUsers', { count: 1000 })}</p> {/* -> dashboard.stats.totalUsers */}
      <p>{d('activeUsers', { count: 150 })}</p> {/* -> dashboard.stats.activeUsers */}
    </div>
  );
}

Поддержка нескольких языков

Автоматический перевод (рекомендуется)

Большинству пользователей следует использовать loadTranslations, чтобы автоматически генерировать переводы из вашей базовой словарной базы:

dictionary.ts
const dictionary = {
  common: {
    save: 'Сохранить',
    cancel: 'Отмена',
    delete: 'Удалить'
  },
  forms: {
    required: 'Это поле обязательно для заполнения',
    email: 'Введите действительный адрес электронной почты'
  }
};

export default dictionary;

Затем создайте функцию loadTranslations, которая будет загружать сгенерированные файлы переводов:

src/loadTranslations.ts
export default async function loadTranslations(locale: string) {
  const translations = await import(`./_gt/${locale}.json`);
  return translations.default;
}

Передайте его в свой <GTProvider>:

src/index.tsx
import loadTranslations from './loadTranslations';
import dictionary from './dictionary';

createRoot(document.getElementById("root")!).render(
  <StrictMode>
    <GTProvider 
      {...config} 
      dictionary={dictionary}
      loadTranslations={loadTranslations}
    >
      <App />
    </GTProvider>
  </StrictMode>
);

GT автоматически генерирует переводы для других языков на основе вашей базовой словарной базы. Запустите npx gtx-cli translate, чтобы создать переводы для всех настроенных языков.

Файлы для ручного перевода (миграция)

Для миграции с других библиотек i18n или при ручном управлении переводами используйте loadDictionary:

src/loadDictionary.ts
export default async function loadDictionary(locale: string) {
  const translations = await import(`../public/locales/${locale}.json`);
  return translations.default;
}

Это загружает JSON‑файлы переводов из каталога public/locales/:

es.json
fr.json
de.json

Выберите подходящий вариант: используйте loadTranslations для новых проектов с автоматической генерацией переводов или loadDictionary при миграции существующих файлов переводов.

Настройка продакшена

Процесс сборки

Добавьте перевод в свой конвейер сборки:

package.json
{
  "scripts": {
    "build": "npx gtx-cli translate && <...YOUR_BUILD_COMMAND...>"
  }
}

Поведение в разработке и в продакшене

  • Разработка: записи словаря переводятся по запросу с использованием dev API key
  • Продакшен: все переводы словаря заранее формируются на этапе сборки

Сочетание с компонентами

Словари и компоненты <T> могут работать вместе:

function MixedApproach() {
  const d = useTranslations();
  
  return (
    <div>
      {/* Словарь для простых строк */}
      <h1>{d('page.title')}</h1>
      
      {/* Компонент T для сложного JSX */}
      <T>
        <p>Это <strong>сложное сообщение</strong> с <a href="/link">ссылками</a>.</p>
      </T>
      
      {/* Словарь для ярлыков формы */}
      <label>{d('forms.email')}</label>
    </div>
  );
}

Дальнейшие шаги

Насколько полезно это руководство?

Словари