Conecta tu Payload CMS a un motor de localización, elige las colecciones y los globales que quieres incluir, y Lingo.dev traduce sus campos localizados a tus idiomas de destino y los vuelve a escribir en Payload en cada idioma.
Funciona con proyectos de Payload 3 que tienen la localización habilitada y usan el editor de texto enriquecido Lexical. El editor anterior, Slate, no es compatible. Se traducen los campos localizados text, textarea y richText. Todo lo demás en el documento se deja tal cual.
La integración de Payload se habilita por organización. Si no la ves en Settings -> Integrations, escríbenos y la activamos por ti.
Antes de empezar#
Necesitas tres cosas:
- Payload 3 con la localización configurada. Asegúrate de que el idioma de origen y el de destino coincidan con los idiomas definidos en tu configuración de Payload.
- Un usuario de servicio con una API key. Configura
useAPIKey: trueen tu colección de autenticación (normalmenteusers), crea un usuario para Lingo.dev y genera una API key para ese usuario en el panel de administración de Payload. Ese usuario necesita acceso de lectura y actualización a cada colección y global que quieras traducir. - Un motor de localización. Su glosario, voz de marca y reglas definen cómo se hacen las traducciones.
Los códigos de idioma deben coincidir con tu configuración de Payload
Los idiomas que elijas en Lingo.dev deben coincidir exactamente con los códigos de localization.locales. Si Payload tiene en y de, elige English y German, no English (United States): en-US y en son idiomas distintos. Usa el defaultLocale de tu Payload como idioma de origen, porque ese es el idioma cuyos cambios monitorea el plugin.
Conecta tu instancia de Payload#
Abre la integración
Ve a Settings -> Integrations y haz clic en Connect debajo de Payload CMS.
Ingresa los datos de tu instancia
| Campo | Qué ingresar |
|---|---|
| Nombre de la conexión | Una etiqueta como Production o Staging |
| URL base de Payload | La URL raíz de tu instancia, por ejemplo https://cms.example.com. Solo HTTPS |
| Slug de la colección de autenticación | La colección a la que pertenece tu API Key de servicio, normalmente users |
| API Key | La API key del usuario de servicio |
| Encabezados personalizados | Opcional. Se envía con cada solicitud a tu instancia |
Lingo.dev verifica la key con tu instancia antes de continuar.
Elige qué traducir
| Configuración | Qué hace |
|---|---|
| Colecciones y globales | Marca las que quieres traducir. Una fila marcada como No read + update seguirá deshabilitada hasta que la persona usuaria de servicio tenga acceso |
| Idioma de origen | El idioma en el que escribe tu equipo editorial. Usa tu defaultLocale de Payload |
| Idiomas de destino | Los idiomas a los que se traducirá |
| Motor | El motor de localización que traducirá este contenido |
| Traducir guardados en borrador | Desactivado traduce solo los cambios publicados. Activado también traduce los guardados en borrador y mantiene las traducciones como borradores |
Instala el plugin
El último paso muestra tu URL de webhook. Cópiala ahora. Solo se muestra una vez. Guárdala como LINGO_WEBHOOK_URL en el entorno de Payload, luego instala el plugin y agrégalo a tu configuración:
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,
}),
],
});Vuelve a desplegar Payload. A partir de ese momento, cada cambio publicado en el idioma de origen se envía a Lingo.dev para traducirse.
Qué hace el plugin
Agrega un endpoint GET /api/lingo/schema que le indica a Lingo.dev cuáles de tus campos son texto localizado, y un hook que avisa a Lingo.dev cuando cambia un documento o global. El alcance, los idiomas y el motor se administran desde el panel, así que puedes cambiarlos sin volver a desplegar. Omite webhookUrl para no usar el hook e iniciar cada traducción desde el panel.
Elige qué se traduce#
La página de conexión tiene tres pestañas: Collections, Globals y Runs.
El alcance se define por colección y por global. Todos los documentos de una colección seleccionada quedan incluidos. Para cambiar el alcance, los idiomas, el motor o la configuración de borradores, haz clic en Edit configuration en el encabezado de la página. Los cambios se aplican en la siguiente ejecución sin necesidad de volver a desplegar.
Dentro de un documento, la configuración de campos de Payload define qué se traduce:
| Campo | Se traduce |
|---|---|
Campos text, textarea y richText marcados como localized: true | Sí |
Los mismos tipos de campo dentro de un group, array, blocks o tabs localizado | Sí |
| Bloques y bloques en línea incrustados en texto enriquecido | Sí, sus campos de texto siguen las mismas reglas |
select, radio, checkbox, number, date, relationship, upload, json, code, email, point | No |
| Campos que no están localizados y no tienen un elemento padre localizado | No |
id, blockType, blockName | No |
El texto enriquecido se traduce como un árbol de Lexical. Se conservan el formato, los enlaces, las cargas y la estructura de bloques, y solo se reemplaza el texto interno. Una oración dividida por texto en negritas o por un enlace se traduce como una sola oración.
Para incluir un campo en el alcance, márcalo como localized: true en Payload y vuelve a desplegar. La siguiente ejecución lo detectará.
Sincroniza y vuelve a traducir#
Ejecuciones automáticas. Con webhookUrl configurado en el plugin, cada vez que guardas un documento o global en el idioma de origen, se notifica a Lingo.dev. Los guardados que se hagan dentro de un periodo corto se consolidan en una sola ejecución. Se ignoran los guardados en otros idiomas, los guardados de borrador (a menos que esté activada la opción Traducir guardados de borrador) y el contenido que esté fuera de tu alcance.
Ejecuciones manuales. Cada fila de colección, global y documento tiene dos botones:
| Botón | Qué hace | Cuándo usarlo |
|---|---|---|
| Sync | Traduce solo lo que cambió desde la última ejecución | Para completar contenido después de conectar o reintentar tras una falla |
| Retranslate | Vuelve a traducir todo en la fila desde cero | Después de cambiar el glosario, la voz de marca o las reglas de tu motor |
Abre una colección para acceder a sus documentos y sincronizarlos uno por uno. Ambas pestañas muestran cuándo se sincronizó por última vez cada elemento.
No se traduce nada al conectar. Para traducir lo que ya tienes, haz clic en Sync en cada colección y global. Agregar un idioma de destino más adelante funciona igual: el siguiente Sync lo completará.
Solo puede haber una ejecución en curso por conexión. Las solicitudes adicionales se ponen en cola y comienzan en orden. Mientras una fila esté cubierta por una ejecución en cola o en curso, sus botones mostrarán Syncing....
Retranslate sobrescribe las ediciones manuales
Retranslate vuelve a generar cada campo traducido dentro de su alcance, incluidas las traducciones que tu equipo haya editado manualmente en Payload. Sync solo vuelve a generar los campos cuyo texto de origen cambió, así que las ediciones manuales en otros campos se conservan.
Sigue una ejecución#
La pestaña Runs muestra cada ejecución con su estado, disparador (Webhook o Manual) y acción (sync o retranslate), hora de inicio y duración. Una ejecución en cola o en curso se puede cancelar desde la lista.
Abre una ejecución para ver en qué etapa está (lectura desde Payload, traducción, escritura de vuelta), el progreso general, el progreso por idioma de destino y los documentos, colecciones y globales que incluye. Cada elemento enlaza al panel de administración de Payload.
| Estado | Significado |
|---|---|
| En cola | En espera de la ejecución que va antes |
| En curso | En progreso |
| Completada | Se escribió de vuelta cada traducción |
| Up to date | Nada dentro del alcance cambió desde la última ejecución. No es una falla |
| Fallida | La ejecución se detuvo. La razón aparece en la parte superior del detalle de la ejecución |
| Cancelada | La detuvo alguien de tu equipo |
Si una ejecución falla, conserva lo que ya escribió. El mensaje de error indica qué documentos no se escribieron, y la siguiente Sync vuelve a intentarlo. Si una persona editora guarda un documento a mitad de la ejecución, se omite y se retoma en la siguiente.
Dónde terminan las traducciones#
Cada traducción se escribe en el mismo documento o global, en su idioma de destino, siguiendo el propio modelo de localización de Payload. Solo se escriben los campos traducidos. Todos los demás campos permanecen intactos. Las escrituras de vuelta se ejecutan como el usuario del servicio y no activan una nueva ejecución.
Las traducciones existentes se conservan. En la primera sincronización de un documento, todo lo que ya tenga un idioma de destino se mantiene y solo se traducen los campos faltantes. Un campo que todavía conserva su valor predeterminado de Payload cuenta como faltante. Usa Retranslate para reemplazar traducciones existentes.
Borradores vs. publicado#
Con Translate draft saves desactivado, que es la opción predeterminada, solo los cambios publicados inician una ejecución, y las traducciones se publican en cuanto se escriben. Payload publica el documento completo, así que cualquier edición de borrador sin publicar también se publica junto con la traducción.
Con esta opción activada, los guardados en borrador también inician ejecuciones. Lingo.dev lee el borrador más reciente del origen y escribe cada traducción como borrador. Nada cambia para tus lectores hasta que alguien publique la traducción en Payload. Úsalo mientras evalúas la calidad de la traducción o cuando las traducciones pasan por revisión.
Administrar la conexión#
Rotar la URL del webhook#
Abre el menú en el encabezado de la página de conexión y elige Regenerar URL del webhook. La URL anterior deja de funcionar de inmediato. Actualiza LINGO_WEBHOOK_URL y vuelve a desplegar. Si editas la conexión, la URL se conserva.
Desconectar#
Desconéctate desde Settings -> Integrations -> Payload CMS. Esto elimina la conexión, su historial de ejecuciones y el registro de lo que se ha traducido. Las traducciones ya escritas permanecen en Payload. Después, elimina LINGO_WEBHOOK_URL o el plugin de tu configuración.
Reconectar significa una nueva URL del webhook
Una conexión nueva obtiene una URL de webhook nueva, así que actualiza LINGO_WEBHOOK_URL y vuelve a desplegar antes de que las ejecuciones automáticas vuelvan a funcionar. La primera sincronización vuelve a leer cada documento dentro del alcance, conserva las traducciones que Payload ya tiene y completa lo que falta.
Límites#
| Límite | Detalle |
|---|---|
| Versión de Payload | Payload 3 con localización configurada |
| Tipos de campo | Campos text, textarea y richText (solo Lexical) marcados como localized |
| Alcance | Colecciones y globales completos. Sin selección por campo |
| Conexiones | Varios por organización, uno por instancia de Payload |
| Ejecuciones simultáneas | Uno por conexión |
| URL base | Solo HTTPS |
Solución de problemas#
La conexión falla con "Payload rejected the API key". Verifica la key, el slug de la colección de autenticación y que useAPIKey esté habilitado en esa colección.
Una colección o global muestra "No read + update". Dale al usuario de servicio acceso de lectura y actualización en la configuración de acceso de esa colección, y luego vuelve a abrir la configuración.
La primera ejecución falla con "The Lingo plugin isn't installed". Agrega @lingo.dev/payloadcms a plugins en la configuración de Payload y vuelve a desplegar. Conectar funciona sin el plugin; sincronizar no.
Publicar en Payload no inicia una ejecución. Verifica que LINGO_WEBHOOK_URL esté configurado, que localization esté configurado, que la colección o global esté dentro del alcance, que el guardado haya sido en el idioma de origen y que haya sido una publicación, no un borrador.
Un campo no se traduce. No tiene localized: true ni en el propio campo ni en un elemento padre, o no es un campo text, textarea o richText.
La conexión muestra "Couldn't reach this Payload instance". Verifica que la instancia esté en línea, que la key siga siendo válida y que cualquier encabezado de la puerta de enlace siga funcionando. Actualiza la conexión en Settings -> Integrations.
