Руководство · Миграция
Миграция с i18next
Уже в продакшене с i18next? @sonenta/react-i18next — это drop-in замена для react-i18next — тот же API useTranslation() и t(): вы просто меняете провайдер, и ваши переводы приходят вживую из CDN. Перенесите ваши существующие файлы locales/ в Sonenta одной командой, затем оставьте код как есть. Импорт создаёт отсутствующие ключи, обновляет каждый перевод и полностью идемпотентен: вы можете перезапускать его из CI без опасений. Вот весь путь: установить, импортировать, опубликовать, проверить, подключить SDK.
Прежде чем начать
Три вещи, и вы готовы к импорту:
- Проект. Создайте его в дашборде и скопируйте его
project_uuid. - Ключ API со скоупом
mcp:*. CLI работает через поверхность MCP — ключ, ограниченный проектом, возвращает403. В справочнике CLI описано, как его создать. - Node 18+ и ваши существующие файлы i18next, разложенные как
<lang>/<namespace>.json(нестандартные раскладки тоже обрабатываются).
1. Установка и инициализация
Установите CLI глобально, сгенерируйте конфигурацию, указывающую на ваш проект, и экспортируйте ключ.
terminal 1# one global install — gives you the `sonenta` command (Node >= 18)2npm i -g @sonenta/cli 4# scaffold sonenta.config.json and point it at your project5sonenta init --project <project_uuid> 7# the CLI talks to the MCP surface — use an mcp:* scoped key8export SONENTA_TOKEN=snt_live_<prefix>.<secret> sonenta init создаёт sonenta.config.json, который можно закоммитить. В CI пропустите init и передайте --project плюс переменную окружения SONENTA_TOKEN. sonenta и SONENTA_* являются каноническими; устаревшая команда sonenta и переменные SONENTA_* всё ещё работают на время перехода.
2. Предпросмотр, затем импорт
Импортёр читает путь каждого файла, чтобы вывести его язык и namespace, поэтому обычное дерево locales/ не требует опций. Сначала выполните dry-run, чтобы увидеть план, затем уберите --dry-run, чтобы применить его.
your repo 1# the importer infers (language, namespace) from each path:2# <lang>/<namespace>.json3locales/4├─ en/5│ ├─ common.json → language en · namespace common6│ └─ checkout.json → language en · namespace checkout7└─ fr/8 ├─ common.json → language fr · namespace common9 └─ checkout.json → language fr · namespace checkout terminal 1# preview first — no writes, prints exactly what WOULD change2sonenta import "./locales/**/*.json" --dry-run 4# the real run — idempotent, safe to repeat5sonenta import "./locales/**/*.json" 7✓ common · checkout (en, fr)8 keys 312 created · 0 reused9 translations 624 created · 0 updated · 0 unchanged10 errors 0 · glossary 0 violations 12# non-standard layout? override the inference per file:13sonenta import strings.fr.json --language fr --namespace common Деревья могут быть вложенными или плоскими — оба импортируются одинаково. --status задаёт входящий статус (draft или translated, по умолчанию translated); --version нацеливается на версию, отличную от версии по умолчанию. Множественные формы, выраженные словарём CLDR ({ one, other }), автоматически сохраняются как формы множественного числа.
3. Публикация в CDN
Импорт наполняет проект; публикация делает его раздаваемым. Создайте релиз, и бандлы распространятся по глобальному CDN, из которого читает SDK.
terminal 1# cut a CDN release so the SDK and your build can fetch it2sonenta releases publish 4→ released "main" · propagating to cdn.sonenta.com Релизы — это неизменяемые снапшоты версии. Перепубликовывайте, как только импортируете новый контент — и SDK, и ваша статическая сборка получают последний релиз.
4. Проверка бандла
Убедитесь, что контент в эфире. Опубликованный бандл — это обычный публичный JSON-файл на каждый язык и namespace — заберите один напрямую или откройте проект в дашборде.
terminal 1# the published bundle is public — no auth needed2curl -s https://cdn.sonenta.com/p/<project_uuid>/main/latest/fr/common.json Получили 404 для языка? Он ещё не входит в число языков проекта, либо релиз не распространился — подождите несколько секунд и повторите.
5. Направьте ваш SDK на Sonenta
Замените ваш бэкенд i18next на провайдер Sonenta. Ваши вызовы t(), ключи и namespace остаются прежними — переводы теперь приходят из бандла CDN, который вы только что опубликовали.
main.tsx 1// src/main.tsx — point @sonenta/react-i18next at the same project2import { SonentaProvider } from "@sonenta/react-i18next"; 4<SonentaProvider5 projectUuid="<project_uuid>"6 token={import.meta.env.VITE_SONENTA_TOKEN}7 defaultLocale="fr"8 namespaces={["common", "checkout"]}9>10 <App />11</SonentaProvider> Ключи, содержащие точки (версия, цена, библейская ссылка)? Задайте keySeparator={false} и переведите проект в плоский режим — см. руководство Плоские или вложенные ключи. Иначе вложенный режим по умолчанию работает как есть.
Перезапускается в любой момент
sonenta import идемпотентен: повторный импорт идентичного контента ничего не меняет (0 создано, 0 обновлено, N без изменений). Встройте его в CI, чтобы держать Sonenta в синхронизации с вашим репозиторием — он создаёт только то, чего не хватает, и обновляет только то, что действительно изменилось.
Что обрабатывает импортёр
- Вложенный или плоский. Обе формы JSON импортируются в одни и те же ключи — без предварительной обработки.
- Множественные формы. Словари множественного числа CLDR (
{ one, other, … }, с обязательнымother) автоматически становятся ключами множественного числа. - Устойчивость на уровне файла. Неизвестный язык или namespace сообщается как ошибка по конкретной единице — остальная часть импорта всё равно проходит.
- Проверки по глоссарию. Импортируемые переводы проходят через ваш глоссарий; нарушения перечисляются и пропускаются при строгом контроле.
- Очистка отсутствующих ключей. Открытые события об отсутствующих ключах для импортированных ключей разрешаются, как только приходят значения.