TTyko

Пакети / Мови

@tykonpm/multilang

v0.4.0

29 мов з українським джерелом, React-провайдер, адмінка й черга перекладу сайту.

$ npm i @tykonpm/multilang

← Усі пакети Tyko

Мультимовність і керування перекладами для сайтів: функціонал + необов’язкові React-екрани. Українська (uk) — джерело. Немає обов’язкової залежності від Supabase чи конкретного ШІ-провайдера. React потрібен лише для React-частин.

Документація

Документація в main описує наявний код, який може ще чекати релізу. Перевірте версію та exports установленого пакета; /translate-all і /translate-all/react потрібні для повного модуля. Не встановлюйте неіснуючу версію лише тому, що її згадано в плані.

Встановлення

sh
npm view @tykonpm/multilang version
npm install @tykonpm/multilang
# або: bun add @tykonpm/multilang

ESM і CommonJS, декларації TypeScript. Для React-частин React >=18; для CLI Node >=18. Пакет не містить ваших словників чи секретів.

Частини пакета

ІмпортМожливості
@tykonpm/multilangLANGUAGES (29), SOURCE_LANG, detectLang, interpolate, plural, sourceHash, phraseStatus, coverage, createMemoryStore, словники export/import, помічники ШІ
@tykonpm/multilang/reactMultilangProvider, useT, T, LanguageSwitcher
@tykonpm/multilang/adminTranslationsAdmin: одна мова, прогрес, пошук, ручне редагування, missing/stale, ШІ-пакети, JSON імпорт/експорт
@tykonpm/multilang/supabasecreateSupabaseStore(client): необов’язковий адаптер ui_translations
@tykonpm/multilang/translate-allcreateTranslator, джерела, черга, план, маскування, глосарій, адаптери ШІ й JobStore
@tykonpm/multilang/translate-all/reactTranslateAllPanel, TranslationMatrix, TranslationLauncher, TranslationJobs, TranslationReview, useTranslationQueue

Переклади на сайті

tsx
import { MultilangProvider, LanguageSwitcher, T, useT } from '@tykonpm/multilang/react';
import { createMemoryStore, type Lang } from '@tykonpm/multilang';

// Стабільні посилання: не створюйте store/loadLocale заново на кожному render.
const store = createMemoryStore([
  { lang: 'en', source: 'Привіт, {name}', text: 'Hello, {name}' },
]);
const loaders: Partial<Record<Lang, () => Promise<Record<string, string>>>> = {
  en: async () => ({ 'Привіт, {name}': 'Hello, {name}' }),
};
const loadLocale = async (lang: Lang) => loaders[lang]?.() ?? {};

export function Example() {
  return <MultilangProvider store={store} loadLocale={loadLocale}>
    <LanguageSwitcher />
    <Greeting />
  </MultilangProvider>;
}
function Greeting() {
  const { t } = useT();
  return <><h1>{t('Привіт, {name}', { name: 'Олена' })}</h1><T text="Вітаємо" /></>;
}

Для справжніх lazy-словників створіть явну мапу en: () => import('./locales/en.json').then(m => m.default) тощо: не всі збирачі підтримують довільний динамічний шлях.

Словники завантажуються при перемиканні мови; записи store мають перевагу. Якщо перекладу немає — український текст. Provider установлює lang/dir, запам’ятовує мову в localStorage після hydration. allowed обмежує початкове визначення мови, а LanguageSwitcher languages — видимі варіанти; передавайте обидва. Provider не створює окремі мовні URL, canonical чи hreflang.

Збір фраз

sh
npx tyko-multilang-extract src src/lib/ui-strings.json

Результат — масив українських рядків із літеральних t('…'), t("…"), <T text="…">, <TranslatedText text="…"> у JS/TS. Створіть каталог призначення заздалегідь. Це regex-збирач, не AST: він не збирає весь JSX, CMS, template literals чи динамічні ключі; перевірте результат і додайте джерела CMS окремо.

Проста адмінка

tsx
import { TranslationsAdmin } from '@tykonpm/multilang/admin';
// sources: readonly string[]; store: TranslationStore;
// authorizedTranslate: серверний виклик, що повертає string[] у тому самому порядку.
<TranslationsAdmin sources={sources} store={store}
  languages={['en', 'pl', 'de']} translate={authorizedTranslate}
  onError={showError} />;

Це приклад контракту: sources/store/authorizedTranslate/showError реалізує сайт. Кнопка ШІ тут одразу зберігає результати; для перевірки перед застосуванням використовуйте TranslateAllPanel. Вигляд налаштовується через classNames/labels; перемикач має render prop. Готові екрани містять власні HTML-контроли — це не автоматична заміна всіх контролів вашої дизайн-системи.

Повний переклад сайту

Таблиця: рядки — зареєстровані джерела (сторінки, меню, CMS), стовпці — мови. Запуск по клітинці, рядку, мові, всьому сайту; API також дозволяє вибрані ключі. missing означає відсутні **і застарілі**, all — повторно перекласти все. autoApply: false дає перевірку, true — автоматичне застосування успішних пунктів через ваш адаптер. Докладний приклад у TRANSLATE-ALL.md.

Застарілість

Зберігайте sourceHash українського тексту разом із перекладом. Невідповідний hash означає stale. Старі записи без hash НЕ позначаються stale автоматично. Для CMS використовуйте стабільний key: тоді зміна українського text зберігає зв’язок із попереднім перекладом. Проста адмінка використовує український рядок як ключ: його перейменування без міграції створить missing, а не автоматично зв’яже старий рядок.

Безпека та перевірки

  • Ключі ШІ й privileged clients — лише на сервері. Захищайте кожен метод серверного API, а не тільки сторінку адмінки.
  • Пакет не створює таблиці або ролі сам. Збереження й RLS — відповідальність сайта.
  • Переклад не є HTML-санітизацією. Не відображайте недовірений результат через dangerouslySetInnerHTML.
  • Одна черга потребує одного активного процесора або зовнішнього блокування; пакет не є розподіленою чергою.
  • Тести з mock-провайдером не доводять роботу вашого реального ШІ: перевірте один малий платний пакет окремо.

MIT. Документацію, приклади й сторінку пакета оновлюйте в тому самому релізі, що й API.