# General Translation Knowledge Base: Как перевести JSON-файлы i18n?
URL: https://generaltranslation.com/ru/kb/translate-json-files.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: Переводите только строковые значения в JSON-файле локали. Ключи, не связанные с множественным числом, заполнители вроде {{name}} и теги оставляйте без изменений, но учтите, что ключи для форм множественного числа зависят от языка: например, для польского нужны inbox_few и inbox_many. Используйте инструмент или API с поддержкой формата, а затем разберите и проверьте результат перед вычиткой.
Category: Перевод
Last updated: 2026-10-20
Authors: Kevin Wu, Jackie Chen
Published: 2026-10-20

Здесь речь идёт о файлах локалей, которые загружают библиотеки интернационализации — i18next, react-intl, next-intl, vue-i18n и другие. В таких файлах каждый ключ соответствует строке UI. Для произвольных JSON-данных (ответов API, каталогов товаров) нужен другой подход: там вы сами решаете для каждого поля, переводить его или нет.

## Как выглядят JSON-файлы локалей

Большинство файлов локалей имеют вложенную структуру: ключи сгруппированы в объекты, как показано ниже. В плоском файле тот же путь записывается одним ключом через точку, например `"nav.home": "Home"`.

```json title="locales/en/common.json"
{
  "nav": { "home": "Home", "save": "Save" },
  "greeting": "Hello, {{name}}!",
  "inbox_one": "You have {{count}} new message",
  "inbox_other": "You have {{count}} new messages",
  "terms": "Read our <1>terms</1> before you continue."
}
```

Синтаксис строк внутри файла зависит от библиотеки, и при переводе его нужно сохранить в точности:

* **i18next** интерполирует значения через двойные фигурные скобки (`{{name}}`) и хранит формы множественного числа в отдельных ключах с [суффиксами](https://www.i18next.com/translation-function/plurals) вроде `_one`, `_few`, `_many` и `_other` — в соответствии с правилами множественного числа каждого языка. Компонент `<Trans>` из react-i18next добавляет нумерованные теги, например `<1>terms</1>`.
* **react-intl и next-intl** хранят сообщения ICU: заполнители в них обозначаются одинарными фигурными скобками, а формы множественного числа задаются прямо внутри строки: `{count, plural, one {# message} other {# messages}}`. (См. [Что такое формат сообщений ICU?](/kb/icu-message-format)).
* **vue-i18n** использует заполнители в одинарных фигурных скобках и разделяет формы множественного числа вертикальной чертой: `no apples | one apple | {count} apples` ([обработка форм множественного числа во vue-i18n](https://vue-i18n.intlify.dev/guide/essentials/pluralization)).

Важно и то, как названы ключи: зачастую переводчик видит только ключ и значение. (См. [Как называть ключи перевода i18n?](/kb/i18n-key-naming)).

## Что идёт не так, если вставить JSON в переводчик

Универсальный переводчик воспринимает файл как обычный текст, поэтому его структура оказывается под угрозой:

* **Ключи переводятся.** `"nav"` превращается в `"nawigacja"`, и приложение больше не может найти строку.
* **Заполнители меняются.** `{{name}}` превращается в `{{nombre}}` или теряется фигурная скобка — и интерполяция ломается во время выполнения.
* **Теги ломаются.** `<1>terms</1>` переводится, перенумеровывается или удаляется, и ссылка оборачивает уже не те слова.
* **Файл перестаёт быть валидным JSON.** Достаточно типографских кавычек, неэкранированной `"` внутри переведённой строки или висячей запятой — и весь файл не удаётся распарсить.
* **Не хватает ключей множественного числа.** Если переводить `inbox_one` и `inbox_other` по одному ключу, в польской версии не появятся ключи `inbox_few` и `inbox_many`, которые нужны i18next, и для «5 сообщений» не найдётся правильной польской формы. (Категории множественного числа для каждого языка см. в статье [Что такое формат сообщений ICU?](/kb/icu-message-format).)
* **Короткие строки теряют смысл.** `"save": "Save"` по-немецки — это либо *speichern* (сохранить файл), либо *sparen* (сэкономить), а по одному ключу это редко понятно.

## Способы перевода JSON-файлов локалей

| Подход                                                   | Ключи и заполнители                                                                                                              | Формы множественного числа                                                                   | Контекст для коротких строк                                                              | Отслеживание изменений                                                        |
| -------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
| Вручную или силами переводчика, работающего с файлом     | Безопасно, если человек внимателен                                                                                               | Человек добавляет их сам, если знает правила                                                 | Человек может уточнить                                                                   | Вручную при каждом изменении                                                  |
| Онлайн-переводчик JSON (загрузить файл, скачать перевод) | Зависит от инструмента; сначала проверьте на файле с большим количеством заполнителей                                            | Зависит от инструмента                                                                       | Зависит от инструмента                                                                   | Повторная загрузка файла при каждом изменении                                 |
| Скрипт для DeepL или Google Cloud Translation API        | Вы обходите JSON и отправляете только значения; API документов DeepL также принимает `.json` и по умолчанию защищает заполнители | Недостающие ключи вы генерируете сами                                                        | Параметр `context` в DeepL; в Google контекст для отдельных строк задать нельзя          | Вы перезапускаете скрипт и сравниваете результат                              |
| Промпт для LLM с файлом                                  | Обычно сохраняются, но гарантий нет                                                                                              | Добавляются, если попросить и перечислить категории                                          | Всё, что вы укажете в промпте                                                            | Вы перезапускаете промпт и проверяете результат каждого запуска               |
| General Translation CLI                                  | Считывает структуру JSON и переводит значения                                                                                    | Переводит существующие записи; проверьте наборы форм множественного числа для целевого языка | Заметки и ограничения длины для каждого ключа, общие Glossary и пользовательские промпты | Повторно использует совпадающие переводы; генерирует обновления перед сборкой |
| Система управления переводами (TMS)                      | Файлы разбираются с учётом формата, поэтому ключи не пострадают                                                                  | Зависит от TMS и формата файла                                                               | Скриншоты, комментарии и описания для каждого ключа                                      | Синхронизация файлов через интеграцию TMS с репозиторием                      |

Два варианта со скриптами стоит рассмотреть подробнее. В [API документов](https://developers.deepl.com/api-reference/document) DeepL формат `json` указан как поддерживаемый; по умолчанию заполнители вроде `{stars}` или `{{userName}}` сохраняются без изменений, а ICU-скелеты множественного числа защищены — переводится только текст их ветвей. [Перевод документов](https://docs.cloud.google.com/translate/docs/advanced/translate-documents) в Google принимает файлы Office и PDF, но не JSON, а публичный сайт Google Translate позволяет загружать только `.docx`, `.pdf`, `.pptx` и `.xlsx`, поэтому с Google придётся самостоятельно извлекать строковые значения и отправлять их в текстовый API.

Для разового перевода небольшого файла подойдёт внимательная ручная работа или API документов DeepL. Скрипт или промпт для LLM выбирайте, если готовы сами отвечать за проверку и повторные запуски. General Translation подходит, если нужно, чтобы сгенерированные и проверенные каталоги выпускались вместе с изменениями кода, а текущая библиотека рендеринга оставалась прежней. [Система управления переводами](/kb/what-is-a-translation-management-system) нужна, когда команда переводчиков работает вне кодовой базы.

## Как переводить JSON-файлы с помощью General Translation

Если файлы хранятся в вашем репозитории и меняются с каждым релизом, поддерживать их в актуальном состоянии может одна команда в процессе сборки. CLI от General Translation, `gt`, переводит JSON-файлы локалей, включая каталоги i18next и каталоги на основе ICU. При этом библиотеку, которая выполняет их рендеринг, можно оставить. Установите CLI командой `npm install gt --save-dev`, выполните [`npx gt init`](/docs/cli/reference/commands/init), чтобы создать `gt.config.json` и войти в аккаунт, а затем укажите в `files.json.include` путь к исходным файлам. Заполнитель `[locale]` сообщает CLI, откуда читать исходную локаль и куда записывать каждую целевую локаль:

```json title="gt.config.json"
{
  "defaultLocale": "en",
  "locales": ["de"],
  "files": {
    "json": {
      "include": ["locales/[locale]/*.json"]
    }
  }
}
```

Если проект уже существует, сначала выполните [`npx gt upload`](/docs/cli/reference/commands/upload), чтобы импортировать исходные файлы и проверенные переводы.

Затем [`npx gt translate`](/docs/cli/reference/commands/translate) читает все файлы в `locales/en/` и записывает немецкие файлы в `locales/de/` — их остаётся проверить и закоммитить. Добавьте `--dry-run`, чтобы вывести список найденных файлов без обращения к API. В этом примере используются английский и немецкий: в обоих языках количественные сообщения используют показанные выше категории `one` и `other`. При последующих запусках совпадающие переводы могут использоваться повторно.

Если в вашем `package.json` объявлен `i18next` или `next-intl`, CLI сохраняет синтаксис строк этой библиотеки, включая ICU-сообщения. (См. [справочник по формату JSON](/docs/cli/reference/formats/json-files).) Чтобы устранить неоднозначность короткой строки, например «Save», добавьте сопутствующий файл `common.metadata.json` с теми же ключами и укажите для каждой строки заметку `context` или ограничение `maxChars`. (См. [Метаданные, привязанные к ключам](/docs/cli/reference/keyed-metadata).) Для `nav.save` подойдёт заметка вроде «Сохранить отредактированный документ на диск» — так у сервиса будет больше информации, чем одна неоднозначная метка. Кроме того, применяются термины из Glossary и пользовательские промпты из контекстных групп вашего проекта.

Проверяйте сгенерированные формулировки в [редакторе панели управления](/docs/platform/dashboard/guides/reviewing-translations); если проверяющие редактируют скачанные файлы, используйте [`npx gt save-local`](/docs/cli/reference/commands/save-local). Описанные ниже проверки контролируют структуру сообщений независимо от языковой вычитки.

## Проверьте переведённые файлы перед выпуском

Проверяйте результат по тем же правилам формата сообщений и локалей, которые использует ваше приложение:

* **Разберите JSON и сравните ключи без форм множественного числа.** Проверяйте не только ключи верхнего уровня, но и пути вложенных ключей. Отсутствующие или переименованные ключи могут сломать поиск по ключу, даже если JSON разбирается без ошибок. Обрабатывайте массивы и нестроковые значения в соответствии со схемой вашего приложения.
* **Проверяйте формы множественного числа i18next как группы связанных ключей.** Группируйте ключи вроде `inbox_one` и `inbox_other` по базовому ключу, а затем сверяйте их с категориями целевой локали. Для польского нужны ещё `inbox_few` и `inbox_many`: это обязательные дополнения, а не лишние ключи. Для японского достаточно одного `inbox_other`. i18next опирается на `Intl.PluralRules` и дополнительно поддерживает специальную форму `_zero`; применяйте правила, соответствующие количественным или порядковым сообщениям. (См. [правила множественного числа i18next](https://www.i18next.com/translation-function/plurals).)
* **Сохраняйте заполнители и теги в каждой переведённой форме.** Не забудьте проверить и вновь добавленные формы множественного числа. `{{name}}` по-прежнему должен ссылаться на `name`, а нумерованные теги — указывать на нужные компоненты, даже если их порядок изменился.
* **Разбирайте ICU-сообщения и сравнивайте их аргументы.** Используйте парсер, например [FormatJS ICU message parser](https://formatjs.github.io/docs/icu-messageformat-parser/), а не регулярные выражения для вложенных фигурных скобок. Одного разбора недостаточно: если заменить аргумент множественного числа `count` на `total`, синтаксис останется корректным, но сообщение перестанет соответствовать значению, которое передаёт приложение. Проверяйте имена и типы аргументов, теги форматированного текста, варианты select, селекторы точных чисел вроде `=0` и смещения plural. Учитывайте, что категории множественного числа зависят от локали: обязательная ветка `other` в ICU служит резервным вариантом, поэтому ICU-сообщения не обязаны содержать все категории CLDR.

Отсутствие ключей множественного числа не приводит к явным ошибкам. В этом польском файле есть все четыре категории, а при переводе ключ за ключом в нём остались бы только `inbox_one` и `inbox_other`:

```json title="locales/pl/common.json"
{
  "inbox_one": "Masz {{count}} nową wiadomość",
  "inbox_few": "Masz {{count}} nowe wiadomości",
  "inbox_many": "Masz {{count}} nowych wiadomości",
  "inbox_other": "Masz {{count}} nowej wiadomości"
}
```

Если загрузить такой файл, переведённый ключ за ключом, в i18next 26.5.3 с `fallbackLng: 'en'`, то для каждого числа, требующего формы `few` или `many`, будет использоваться английский текст, а не польская форма `other`:

```text title="Output"
count  category  key-by-key file              complete file
1      one       Masz 1 nową wiadomość        Masz 1 nową wiadomość
2      few       You have 2 new messages      Masz 2 nowe wiadomości
5      many      You have 5 new messages      Masz 5 nowych wiadomości
22     few       You have 22 new messages     Masz 22 nowe wiadomości
1.5    other     Masz 1.5 nowej wiadomości    Masz 1.5 nowej wiadomości
```

Дробное число выводится как `1.5`, поскольку значение не отформатировано как число; если возможны дробные значения, отформатируйте его с учётом локали. Наконец, загрузите сообщения через библиотеку интернационализации вашего приложения и проверьте их в контексте. Протестируйте значения, при которых выбирается каждая форма множественного числа, включая ноль и дробные числа, если это применимо. Проверка синтаксиса не покажет, точен ли перевод и умещается ли текст в интерфейсе. Пользовательские правила интерполяции и синтаксис с вертикальной чертой (pipe) в vue-i18n требуют проверок, адаптированных к этим форматам.

## Ключевые выводы

* Переводите значения, сохраняя синтаксис сообщений. Ключи без форм множественного числа не меняются; набор ключей с формами множественного числа зависит от языка.
* Категории множественного числа в разных языках различаются: для польского нужны ключи `_few` и `_many`, которых нет в английском источнике.
* API DeepL для перевода документов принимает JSON и по умолчанию защищает заполнители; перевод документов в Google не поддерживает JSON.
* Чтобы перевести такие файлы с помощью CLI `gt`, задайте в `files.json.include` паттерн с `[locale]` и выполните [`npx gt translate`](/docs/cli/reference/commands/translate); метаданные, привязанные к ключам, позволяют задать контекст и ограничения длины для отдельных строк.
* Проверяйте наборы форм множественного числа i18next для каждой целевой локали и разбирайте сообщения ICU парсером, а не проверяйте вложенный синтаксис регулярными выражениями.

## Related questions

- [Что такое формат сообщений ICU?](https://generaltranslation.com/ru/kb/icu-message-format.mdx): Формат сообщений ICU — это синтаксис, позволяющий уместить в одной переводимой строке переменные, формы множественного числа, варианты выбора (select) и порядковые числительные, например {count, plural, one {# file} other {# files}}. Каждый язык использует только нужные ему категории множественного числа CLDR: в английском это one и other, а в польском к ним добавляются few и many.
- [Как называть ключи переводов i18n?](https://generaltranslation.com/ru/kb/i18n-key-naming.mdx): Называйте ключи по тому, где отображается текст и что он означает, например checkout.summary.title, а не по его английской формулировке. Для каждого отдельного случая использования заводите собственный ключ, даже если английский текст совпадает: в немецком кнопка Open переводится как Öffnen, а статус Open — как Offen.
- [General Translation против i18next, react-intl и next-intl: какую библиотеку интернационализации выбрать?](https://generaltranslation.com/ru/kb/general-translation-vs-i18n-libraries.mdx): Библиотеки с открытым исходным кодом, такие как i18next, react-intl и next-intl, ничего не переводят. Они лишь отображают переводы, которые вы сами помещаете в файл каталога для каждого языка, — их пишете вы, ваши переводчики или сторонний сервис. Библиотеки General Translation тоже имеют открытый исходный код и делают то же самое, но General Translation ещё и выполняет перевод, используя ваш код как контекст.
- [Можно ли делать i18n без файлов перевода?](https://generaltranslation.com/ru/kb/i18n-without-translation-files.mdx): Да. Библиотеки gt-react и gt-next от General Translation обеспечивают i18n для React и Next.js без ключей перевода и без отдельного JSON-файла для каждого языка, который приходится поддерживать. Тексты остаются встроенными в JSX внутри компонента `<T>`, а команда gt translate генерирует переводы для каждого языка во время сборки, учитывая контекст из вашего кода. Locadex может поддерживать их в актуальном состоянии через пул-реквесты.
- [Достаточно ли точен ИИ-перевод для приложения в рабочей среде?](https://generaltranslation.com/ru/kb/is-ai-translation-accurate.mdx): Для распространённых языков — зачастую да, но только после проверки на ваших языках, строках UI и контенте с повышенными рисками. На WMT25 Gemini 2.5 Pro не уступил эталонным переводам, выполненным людьми, или превзошёл их в 10 из 16 языковых пар, однако бенчмарк на документах не показывает, готовы ли к выпуску короткие строки интерфейса.

## Previous and next questions

- Previous question: [Как определить язык браузера пользователя?](https://generaltranslation.com/ru/kb/detect-user-language.mdx)
- Next question: [Как перевести Markdown и MDX, не нарушив синтаксис?](https://generaltranslation.com/ru/kb/translate-markdown-files.mdx)

## Sitemap

See the [Knowledge Base sitemap](https://generaltranslation.com/ru/kb/sitemap.md) for every article.
