Подключите Payload CMS к движку локализации, выберите коллекции и глобальные объекты — и Lingo.dev переведёт локализованные поля в нужные локали и запишет результат обратно в Payload под каждой локалью.
Работает с проектами Payload 3, в которых включена локализация и используется редактор Lexical. Старый редактор Slate не поддерживается. Переводятся локализованные поля text, textarea и richText. Всё остальное в документе остаётся как есть.
Интеграция с Payload включается на уровне организации. Если в разделе Settings -> Integrations её нет — напишите нам, и мы активируем её для вас.
Перед началом#
Вам понадобятся три вещи:
- Payload 3 с настроенной локализацией. Убедитесь, что исходная и целевая локали совпадают с локалями в конфигурации Payload.
- Сервисный пользователь с API-ключом. Задайте
useAPIKey: trueдля коллекции аутентификации (обычноusers), создайте пользователя для Lingo.dev и сгенерируйте ему API-ключ в панели администрирования Payload. Пользователь должен иметь права на чтение и обновление всех нужных коллекций и глобальных объектов. - Движок локализации. Его глоссарий, тональность бренда и правила задают стиль переводов.
Коды локалей должны совпадать с конфигом Payload
Локали в Lingo.dev должны точно совпадать с кодами в localization.locales. Если в Payload заданы en и de, выбирайте English и German, а не English (United States): en-US и en — разные локали. В качестве исходной локали используйте defaultLocale из Payload — именно за ней плагин следит на предмет изменений.
Подключение инстанса Payload#
Откройте интеграцию
Перейдите в Settings -> Integrations и нажмите Connect рядом с Payload CMS.
Введите данные экземпляра
| Поле | Что вводить |
|---|---|
| Название подключения | Понятное название, например Production или Staging |
| Payload Base URL | Корневой URL инстанса, например https://cms.example.com. Только HTTPS |
| Auth Collection Slug | Коллекция, к которой относится служебный API-ключ, обычно users |
| API-ключ | API-ключ сервисного пользователя |
| Пользовательские заголовки | Необязательно. Отправляется с каждым запросом к вашему экземпляру |
Lingo.dev проверит ключ в вашем экземпляре перед тем, как двигаться дальше.
Выберите, что переводить
| Настройка | Что делает |
|---|---|
| Коллекции и глобальные объекты | Отметьте нужные. Строка с пометкой No read + update остаётся неактивной, пока служебный пользователь не получит к ней доступ |
| Исходная локаль | Локаль, в которой работают редакторы. Используйте defaultLocale из Payload |
| Целевые локали | Локали для перевода |
| Движок | Движок локализации для этого контента |
| Переводить черновики | Выкл. — переводятся только опубликованные изменения. Вкл. — переводятся и черновики, переводы тоже сохраняются как черновики |
Установите плагин
На последнем шаге появится URL вебхука. Скопируйте его сразу — он отображается только один раз. Сохраните его как LINGO_WEBHOOK_URL в переменных окружения Payload, затем установите плагин и добавьте его в конфигурацию:
pnpm add @lingo.dev/payloadcmsimport { buildConfig } from "payload";
import { lingo } from "@lingo.dev/payloadcms";
export default buildConfig({
// ...your collections, globals, and localization config
plugins: [
lingo({
webhookUrl: process.env.LINGO_WEBHOOK_URL,
}),
],
});Передеплойте Payload. Теперь каждое изменение, опубликованное в исходной локали, будет отправляться в Lingo.dev для перевода.
Что делает плагин
Плагин добавляет эндпоинт GET /api/lingo/schema, который сообщает Lingo.dev, какие поля содержат локализованный текст, и хук, уведомляющий Lingo.dev при изменении документа или глобального объекта. Область охвата, локали и движок настраиваются в дашборде — без передеплоя. Уберите webhookUrl, чтобы отключить хук и запускать переводы вручную из дашборда.
Что переводится#
На странице подключения три вкладки: Collections, Globals и Runs.
Область охвата задаётся отдельно для каждой коллекции и глобального объекта. В выбранную коллекцию входят все её документы. Чтобы изменить охват, локали, движок или настройку черновиков, нажмите Изменить конфигурацию в заголовке страницы. Изменения применяются при следующем запуске — без передеплоя.
Внутри документа то, что переводится, определяется конфигурацией полей в Payload:
| Поле | Переводится |
|---|---|
Поля text, textarea и richText, помеченные как localized: true | Да |
Те же типы полей внутри локализованных group, array, blocks или tabs | Да |
| Блоки и встроенные блоки внутри форматированного текста | Да, их текстовые поля по тем же правилам |
select, radio, checkbox, number, date, relationship, upload, json, code, email, point | Нет |
| Поля без локализации и без локализованного родителя | Нет |
id, blockType, blockName | Нет |
Форматированный текст переводится как дерево Lexical. Форматирование, ссылки, загрузки и структура блоков сохраняются — меняется только сам текст. Предложение, разбитое жирным выделением или ссылкой, переводится целиком.
Чтобы добавить поле в область охвата, пометьте его localized: true в Payload и передеплойте. Следующий запуск его подхватит.
Синхронизация и повторный перевод#
Автоматический запуск. Если в плагине указан webhookUrl, каждое сохранение документа или глобальной переменной в исходной локали отправляет уведомление в Lingo.dev. Сохранения, сделанные за короткий промежуток времени, объединяются в один запуск. Сохранения в других локалях, черновые сохранения (если не включён параметр Переводить черновые сохранения), а также контент за пределами вашей области действия игнорируются.
Ручные запуски. У каждой коллекции, глобального объекта и строки документа есть две кнопки:
| Кнопка | Что делает | Когда использовать |
|---|---|---|
| Sync | Переводит только то, что изменилось с последнего запуска | Заполнение контента после подключения или повтор после сбоя |
| Retranslate | Переводит всю строку заново, с нуля | После изменения глоссария, тональности бренда или правил движка |
Откройте коллекцию, чтобы перейти к документам и синхронизировать их по одному. На обеих вкладках видно, когда каждый элемент синхронизировался последний раз.
При подключении ничего не переводится. Чтобы перевести уже существующий контент, нажмите Синхронизировать для каждой коллекции и глобального объекта. Добавление целевой локали позже работает так же: следующая синхронизация её заполнит.
На одно подключение — один запуск одновременно. Остальные запросы встают в очередь и выполняются по порядку. Пока строка охвачена запущенным или ожидающим запуском, её кнопки показывают Синхронизация…
Retranslate перезаписывает ручные правки
Повторный перевод перегенерирует все переведённые поля в области охвата, включая переводы, отредактированные командой вручную в Payload. Синхронизация перегенерирует только поля, в которых изменился исходный текст, — ручные правки в остальных местах сохраняются.
Наблюдение за запуском#
Вкладка Запуски показывает все запуски: статус, триггер (Вебхук или Вручную, синхронизация или повторный перевод), время начала и длительность. Запуск в очереди или активный можно отменить прямо из списка.
Откройте запуск, чтобы увидеть текущий этап (чтение из Payload, перевод, запись обратно), общий прогресс, прогресс по каждой целевой локали, а также документы, коллекции и глобальные объекты, которые он охватывает. Каждый элемент ведёт на панель администрирования Payload.
| Статус | Значение |
|---|---|
| В очереди | Ожидает завершения предыдущего запуска |
| Выполняется | В процессе |
| Завершён | Все переводы записаны |
| Актуален | В области охвата ничего не изменилось с последнего запуска. Это не ошибка |
| Ошибка | Запуск остановлен. Причина показана вверху страницы с деталями запуска |
| Отменён | Остановлен кем-то из команды |
Если запуск завершился с ошибкой, всё уже записанное сохраняется. В сообщении об ошибке — список документов, которые не удалось записать: следующая синхронизация повторит попытку. Документ, сохранённый редактором во время запуска, пропускается и попадёт в очередь при следующем запуске.
Куда попадают переводы#
Каждый перевод записывается в тот же документ или глобальный объект в целевой локали — так работает стандартная модель локализации Payload. Записываются только переведённые поля, остальные не затрагиваются. Обратная запись выполняется от имени сервисного пользователя и не запускает новый запуск.
Существующие переводы сохраняются. При первой синхронизации документа то, что уже есть в целевой локали, остаётся на месте — переводятся только отсутствующие поля. Поле со значением по умолчанию Payload считается отсутствующим. Чтобы заменить существующие переводы, используйте Повторный перевод.
Черновики и опубликованные материалы#
Если перевод при сохранении черновика отключён (по умолчанию), запуск инициируется только при публикации изменений, а переводы публикуются сразу после записи. Payload публикует документ целиком, поэтому все неопубликованные правки в черновике выходят в свет вместе с переводом.
При включённом параметре черновики тоже запускают переводы. Lingo.dev читает последний черновик исходного документа и записывает каждый перевод как черновик. Для читателей ничего не меняется, пока кто-то не опубликует перевод в Payload. Используйте этот режим при оценке качества переводов или когда переводы проходят проверку.
Управление подключением#
Смена URL вебхука#
Откройте меню в заголовке страницы подключения и выберите Regenerate webhook URL. Старый URL перестаёт работать сразу. Обновите LINGO_WEBHOOK_URL и разверните заново. Редактирование подключения не меняет URL.
Отключение#
Отключитесь в разделе Настройки → Интеграции → Payload CMS. Это удалит подключение, историю запусков и данные о переведённом контенте. Уже записанные переводы останутся в Payload. После этого удалите LINGO_WEBHOOK_URL или плагин из конфигурации.
При повторном подключении создаётся новый webhook URL
Новое подключение получает новый URL вебхука — обновите LINGO_WEBHOOK_URL и передеплойте, прежде чем автоматические запуски заработают снова. Первая синхронизация перечитает все документы в области охвата, сохранит переводы, которые уже есть в Payload, и заполнит пробелы.
Ограничения#
| Ограничение | Детали |
|---|---|
| Версия Payload | Payload 3 с настроенной локализацией |
| Типы полей | text, textarea и richText (только Lexical), помеченные как localized |
| Область применения | Целые коллекции и глобальные объекты. Без выбора отдельных полей |
| Подключения | Несколько на организацию, один на экземпляр Payload |
| Параллельные циклы | Один на подключение |
| Базовый URL | Только HTTPS |
Устранение неполадок#
Подключение завершается ошибкой «Payload rejected the API key». Проверьте ключ, слаг коллекции аутентификации и убедитесь, что useAPIKey включён для этой коллекции.
Коллекция или глобальный объект показывает «No read + update». Предоставьте сервисному пользователю права на чтение и обновление в настройках доступа этой коллекции, затем снова откройте конфигурацию.
Первый запуск завершается ошибкой «The Lingo plugin isn't installed». Добавьте @lingo.dev/payloadcms в раздел plugins конфигурации Payload и передеплойте. Подключение работает без плагина, а синхронизация — нет.
Публикация в Payload не запускает перевод. Проверьте, что LINGO_WEBHOOK_URL задан, localization настроен, коллекция или глобальный объект входит в область охвата, сохранение было в исходной локали и это была публикация, а не черновик.
Поле не переводится. У него или у его родителя нет localized: true, либо это не поле типа text, textarea или richText.
Подключение показывает «Couldn't reach this Payload instance». Проверьте, что экземпляр работает, ключ действителен и заголовки шлюза по-прежнему корректны. Обновите подключение в разделе Настройки → Интеграции.
