Sistema de traducción
Qué es esto
ComStack cuenta con dos sistemas de traducción. Esta página cubre la traducción de páginas: la traducción automática de documentación y páginas personalizadas al momento de publicar. Para la traducción de agentes de voz en vivo (detección de idioma en tiempo real durante conversaciones), consulta la documentación del agente de voz.
Cómo funciona
Al publicar, cada página promocionada se traduce automáticamente a todos los idiomas configurados para tu proyecto. El proceso sigue estos pasos:
- Promocionar borradores a versión en vivo
- Traducir automáticamente cada página promocionada a todos los idiomas configurados (en paralelo)
- Promocionar los borradores traducidos a versión en vivo
- Compilar y desplegar el sitio
Tanto la herramienta MCP publish-confirm como el endpoint de publicación de la API REST ejecutan el mismo proceso; no hay diferencia en el comportamiento de traducción entre ambos.
Cuándo usarlo
El sistema de traducción se ejecuta automáticamente en cada publicación. Configúralo definiendo los idiomas (locales) en los módulos de tu proyecto:
- Páginas de conocimiento:
modules.knowledge_base.locales - Páginas personalizadas:
modules.custom_pages.locales
Configuración de idioma
Páginas de conocimiento vs. páginas personalizadas
| Módulo | Campo de configuración | Cuándo se traduce |
|---|---|---|
| Páginas de conocimiento (docs markdown) | project.knowledge_base.locales | Al publicar |
| Páginas personalizadas | project.custom_pages.locales | Al publicar |
Los idiomas de las páginas personalizadas siempre deben ser un superconjunto de los idiomas de las páginas de conocimiento.
Invariantes de configuración
Se aplican tres restricciones al escribir en default_locale o en los idiomas de los módulos:
| Regla | Restricción |
|---|---|
default_locale_in_custom_locales | default_locale ∈ modules.custom_pages.locales (si el módulo está activo) |
default_locale_in_knowledge_locales | default_locale ∈ modules.knowledge_base.locales (si el módulo está activo) |
knowledge_subset_of_custom | modules.knowledge_base.locales ⊆ modules.custom_pages.locales (si ambos están activos) |
Cualquier infracción devuelve un 400 con { error: "Locale config drift", violations: [...] }.
Añadir un idioma
PUT /api/projects/:projectId/modules/knowledge_base (o /custom_pages) con un array de locales que incluya nuevos códigos dispara una expansión automática:
- Por cada nuevo idioma × cada página en el idioma original: se genera un borrador traducido
- Los borradores permanecen en estado de borrador; ejecuta
publish+publish-confirmpara promocionarlos - Idempotente: los pares donde ya existe una variante (en vivo o borrador) para
(canonical_slug, locale)se omiten
Un endpoint de vista previa (POST /api/projects/:projectId/modules/knowledge_base/locales/preview) devuelve el manifiesto esperado sin escribir nada.
Slugs traducidos y canonical_slug
Cada idioma obtiene su propia ruta URL nativa. Una página en inglés en /docs/getting-started podría traducirse a /es/docs/empezando.
El campo canonical_slug agrupa todas las variantes de idioma de la misma página:
| Campo | Propósito |
|---|---|
canonical_slug | Clave de agrupación estable entre idiomas; se define al promocionar y no se sobrescribe |
metadata.slug | Ruta URL específica del idioma (diferente por idioma) |
source_doc_id | Apunta al documento original desde el cual se generó la traducción |
canonical_slug se establece una vez y se preserva. Esto asegura que:
- Una variante traducida mantenga el canonical de su idioma original
- Una página renombrada permanezca en el mismo grupo hreflang que sus traducciones existentes
- El paso de promoción reemplace documentos previos tanto por
(metadata.slug, language)como por(canonical_slug, language), permitiendo que páginas re-traducidas con un slug cambiado reemplacen la variante antigua limpiamente
Excepción: slug === "index" nunca se traduce; el slug de la página de inicio permanece como "index" en todos los idiomas.
Qué se traduce por tipo de página
Páginas de conocimiento (markdown)
| Campo | Comportamiento de traducción |
|---|---|
metadata.title | Traducido |
metadata.description | Traducido |
metadata.slug | Traducido — ruta URL en idioma nativo |
content | Markdown traducido |
metadata.sidebar.* | Copiado sin cambios (estructural) |
Páginas personalizadas
Las páginas personalizadas tienen un patrón distinto porque el cuerpo original nunca debe modificarse:
| Campo | Comportamiento de traducción |
|---|---|
title, description | Traducido |
body_source | Copiado byte a byte — el código del autor nunca se modifica |
translatable_strings | El mapa { key: defaultText } se traduce valor por valor; las claves se preservan |
canonical_slug | Copiado idénticamente — las páginas personalizadas no tienen slugs por idioma |
media_variants, og_image | Copiado idénticamente |
Campo translate: false
Las plantillas de documentos pueden declarar campos individuales con translate: false. Estos campos se copian literalmente del idioma original a todos los idiomas de destino en lugar de traducirse. Aplica a title, description, slug y content cuando se declara.
Reparación de traducciones faltantes
Usa repair-translations (herramienta MCP, rol de manager) para rellenar traducciones faltantes bajo demanda:
- Por cada página en el idioma original, genera cualquier variante de idioma activo que aún no exista
- Promociona y despliega
- Idempotente: los pares con una variante existente se omiten
Opciones:
dry_run: true— previsualiza el manifiesto sin escribir nadadoc_id— limita a una sola página originallocale— limita a un solo idioma de destino
repair-translations incluye una protección contra desviaciones: si el canonical_slug de una variante traducida no coincide con el de su original, se marca en drift_skipped[] y se omite. La desviación no se corrige con esta herramienta; se requiere una corrección de datos de canonical_slug específica.
Errores comunes
| Error | Causa | Solución |
|---|---|---|
400: Locale config drift | Una escritura de idioma viola una de las tres invariantes | Verifica qué invariante falla; ajusta default_locale o los arrays de idiomas |
400: missing_source_index | Se añade un idioma pero no existe una página slug=index en el idioma por defecto | Publica primero una página index en el idioma por defecto |
| Borradores de traducción no visibles | La expansión genera borradores; requieren una publicación para estar en vivo | Ejecuta publish + publish-confirm tras añadir el idioma |
| Entradas hreflang duplicadas | Dos documentos originales comparten el mismo canonical_slug | Asegúrate de que cada página tenga un canonical_slug único |
Relacionado
- Idiomas — todos los idiomas soportados, códigos BCP-47, idiomas RTL
- API de publicación — el proceso de publicación que dispara la traducción
- Catálogo de herramientas —
repair-translationsypublish-confirm