Flujo i18n en Vue 3 para 500+ claves sin sorpresas en producción
Un flujo práctico de i18n en Vue 3 para apps grandes: nombres de claves, plurales, comprobaciones de QA y pasos de lanzamiento para evitar traducciones faltantes en producción.

Qué falla cuando hay más de 500 claves i18n
Cuando tu app supera unas pocas centenas de cadenas, lo primero que suele romperse normalmente no es Vue I18n. Es la consistencia. La gente añade claves con estilos distintos, duplica la misma idea con nombres diferentes y nadie está seguro de qué mensajes pueden eliminarse con seguridad.
Las traducciones faltantes también dejan de ser raras. Aparecen en rutas de usuario normales, especialmente en pantallas menos usadas como configuración, estados de error, estados vacíos y notificaciones.
Cuando falta una traducción, los usuarios suelen ver uno de tres fallos: una interfaz en blanco (un botón sin etiqueta), claves sin procesar (como checkout.pay_now) o un fallback extraño donde parte de la página cambia de idioma. Ninguno de esos parece un bug menor. Hacen que la app parezca rota.
Por eso importa más un flujo de trabajo i18n para Vue 3 que la librería específica. La librería hace lo que le pidas. A escala, los equipos a menudo no se ponen de acuerdo sobre qué significa “hecho”.
Un ejemplo común: un desarrollador lanza un nuevo flujo de “Invitar compañero” con 40 cadenas nuevas. Se actualiza el archivo en inglés, pero no el archivo en francés. En staging, todo parece bien porque el tester usa inglés. En producción, los usuarios francófonos ven una mezcla de UI traducida y no traducida, y soporte recibe capturas con claves sin traducir.
La solución es definir qué significa “hecho” para la UI traducida. No puede ser solo “cadenas añadidas”. Una definición práctica de hecho suele incluir: las claves siguen reglas de nomenclatura, los locales se compilan sin advertencias de claves faltantes, plurales y variables se renderizan correctamente con datos reales, se comprobó al menos un locale no predeterminado y los cambios de copy se rastrean para que las claves antiguas no queden por ahí olvidadas.
Con más de 500 claves, ganas si tratas la localización como un proceso de lanzamiento, no como una edición de archivos a última hora.
Establece algunas reglas antes de añadir más cadenas
Después de unas pocas centenas de cadenas, el trabajo de traducción deja de ser lo desordenado. La consistencia lo es. Un pequeño conjunto de reglas hace que tu flujo i18n de Vue 3 sea predecible, incluso cuando varias personas tocan el copy cada semana.
Empieza decidiendo qué es un “concepto” y mantén una única fuente de verdad para él. Si la misma idea de UI aparece en cinco lugares (por ejemplo, “Guardar cambios”), quieres una clave, no cinco variaciones como save, saveChanges, save_update y saveBtn. Las claves duplicadas derivan en significados distintos con el tiempo, y los usuarios notan esa inconsistencia.
Después, decide dónde vive el formato. Los equipos a menudo lo separan por accidente: algunos mensajes incluyen puntuación y mayúsculas, otros dependen del código para añadirlo. Elige un enfoque y síguelo.
Un valor práctico por defecto:
- Pon gramática, puntuación y formato orientado al usuario (como “(opcional)”) en el mensaje.
- Mantén el formateo de datos puro en el código (fechas, moneda, unidades), y pasa el resultado al i18n.
- Usa placeholders para nombres y contadores, no concatenación de strings.
- Trata el HTML en mensajes como un caso especial con una regla clara (permitido o no permitido).
Luego define ownership. Decide quién puede añadir nuevas claves, quién revisa el copy en el idioma base y quién aprueba otros locales. Sin esto, las cadenas se añaden con prisas y nunca se revisan.
Finalmente, elige y documenta una estrategia de fallback. Si falta una clave, ¿qué deben ver los usuarios: el nombre de la clave, el texto del locale por defecto o un mensaje genérico seguro? En producción, muchos equipos prefieren hacer fallback al locale por defecto y además registrar el incidente, de modo que los usuarios no queden bloqueados y aun así recibas señales de que algo está mal.
Si construyes apps Vue 3 con un generador como AppMaster (Vue3 web UI más código backend real), estas reglas siguen aplicando. Trata las traducciones como contenido de producto, no como “texto solo para devs”, y evitarás la mayoría de sorpresas de última hora.
Convenciones de nombres de claves que siguen siendo legibles
Más allá de unas pocas centenas de cadenas, la consistencia es el factor multiplicador más importante. Elige un estilo de clave y úsalo (la mayoría usa rutas con puntos como billing.invoice.title). Mezclar puntos, barras, snake_case y mayúsculas aleatorias hace que buscar y revisar sea lento.
Usa claves estables que sobrevivan a cambios de copy. Una clave como “Please enter your email” se rompe en cuanto marketing cambia la frase. Prefiere nombres basados en la intención como auth.email.required o auth.email.invalid.
Agrupa las claves por área del producto o superficie de UI primero, luego por propósito. Piensa en los mismos buckets que ya tiene tu app: auth, billing, settings, support, dashboard. Esto mantiene los archivos de locale más fáciles de escanear y reduce duplicados cuando dos pantallas necesitan la misma idea.
Dentro de cada área, mantén un pequeño conjunto de patrones para piezas de UI comunes:
- Botones:
*.actions.save,*.actions.cancel - Etiquetas:
*.fields.email.label,*.fields.password.label - Ayudas/hints:
*.fields.email.hint - Errores/validación:
*.errors.required,*.errors.invalidFormat - Notificaciones/toasts:
*.notices.saved,*.notices.failed
Los mensajes dinámicos deben decir qué cambia, no cómo. Nombra el mensaje por intención y usa parámetros para las partes variables. Por ejemplo, billing.invoice.dueInDays con {days} es más claro que billing.invoice.dueIn3Days.
Ejemplo (funciona bien en un flujo i18n de Vue 3): orders.summary.itemsCount con {count} para el número, y orders.summary.total con {amount} para el dinero. Cuando alguien lea la clave en el código, debería saber dónde pertenece y por qué existe, aunque el copy final cambie más tarde.
Reglas de plurales y formateo de mensajes sin sorpresas
El texto plural se rompe silenciosamente cuando tratas cada idioma como si fuera inglés. Decide pronto cuándo usarás la sintaxis ICU y cuándo un simple placeholder basta.
Usa reemplazos simples para etiquetas y textos cortos de UI que nunca cambian por número (por ejemplo, "Welcome, {name}"). Cambia a ICU para cualquier cosa basada en conteo, porque mantiene todas las formas en un solo sitio y hace las reglas explícitas.
{
"notifications.count": "{count, plural, =0 {No notifications} one {# notification} other {# notifications}}"
}
Escribe los mensajes de conteo de forma que sean fáciles de traducir. Prefiere una oración completa y mantén el placeholder del número (#) cerca del sustantivo. Evita atajos ingeniosos como reutilizar la misma clave para “1 item” y “2 items” en el código. Los traductores necesitan ver el mensaje entero, no adivinar cómo se ensamblará.
Planifica al menos =0, one y other, y documenta qué esperas para 0. Algunos productos quieren “0 items”, otros prefieren “No items”. Elige un estilo y mantenlo para que la UI sea coherente.
También presta atención a idiomas con más categorías plurales de las que esperas. Muchos idiomas no siguen “uno vs muchos”. Si añades un locale nuevo más tarde, un mensaje con solo one y other puede quedar gramaticalmente mal aun si se renderiza.
Antes de publicar, prueba los plurales con conteos reales en la UI, no solo mirando el JSON. Una comprobación rápida que captura la mayoría de problemas es 0, 1, 2, 5 y 21.
Si construyes una app web Vue3 (por ejemplo, dentro de AppMaster), haz esta prueba en la pantalla real donde aparece el texto. Los problemas de layout, texto truncado y frases raras aparecen allí primero.
Organizar archivos de locale para crecer
Después de unas pocas centenas de cadenas, un único en.json grande se convierte en un cuello de botella. La gente toca el mismo archivo, los conflictos en merges aumentan y se pierde la pista de dónde vive cada copy. Una buena estructura mantiene tu flujo i18n de Vue 3 estable incluso cuando el producto cambia.
Estructuras sugeridas
Para 2 a 5 locales, dividir por feature suele ser suficiente. Mantén el mismo layout de archivos en cada locale para que añadir una clave sea una edición predecible.
locales/en/common.json,locales/en/auth.json,locales/en/billing.jsonlocales/es/common.json,locales/es/auth.json,locales/es/billing.jsonlocales/index.ts(carga y fusiona mensajes)
Para 20+ locales, escala la misma idea pero haz más difícil la deriva. Trata el inglés como la fuente de verdad y aplica que cada locale refleje la misma estructura de carpetas y nombres de archivo. Si aparece un dominio nuevo (por ejemplo, notifications), debe existir en cada locale aunque el texto sea temporal.
Dividir por dominio reduce conflictos en merges porque dos personas pueden añadir cadenas en archivos distintos sin pisarse. Los dominios deben coincidir con cómo está construida tu app: common, navigation, errors, settings, reports, además de carpetas de feature para áreas más grandes.
Mantener las claves consistentes
Dentro de cada archivo, conserva la misma forma de clave en todos los locales: mismo anidado, mismos nombres de clave, distinto texto. Evita claves “creativas” por idioma, aunque una frase sea difícil de traducir. Si en inglés existe billing.invoice.status.paid, cada locale debe tener exactamente esa clave.
Centraliza solo lo que realmente se repite en todas partes: etiquetas de botones, errores genéricos de validación y navegación global. Mantén el copy específico de cada feature cerca del dominio de la feature, incluso si parece reutilizable. “Guardar” pertenece a common. “Guardar método de pago” pertenece a billing.
Contenido largo
Los textos largos de ayuda, pasos de onboarding y plantillas de correo se complican rápido. Unas pocas reglas ayudan:
- Pon las cadenas largas en su propio dominio (por ejemplo,
helpoonboarding) y evita anidamiento profundo. - Prefiere párrafos cortos en lugar de una única cadena enorme, para que los traductores trabajen con seguridad.
- Si marketing o soporte editan el texto con frecuencia, guarda esos mensajes en un archivo dedicado para reducir la rotación en otros sitios.
- Para emails, guarda asunto y cuerpo por separado y mantén los placeholders coherentes (nombres, fechas, importes).
Esta configuración facilita revisar cambios, traducir de forma constante y evitar huecos sorpresa justo antes del lanzamiento.
Un flujo paso a paso para añadir y publicar cadenas
Un flujo i18n estable en Vue 3 tiene menos que ver con herramientas y más con repetir los mismos pasos pequeños cada vez. El nuevo texto de UI no debería llegar a producción sin una clave, un mensaje por defecto y un estado de traducción claro.
Empieza añadiendo la clave a tu locale base (a menudo en). Escribe el texto por defecto como copy real, no como un placeholder. Esto da a producto y QA algo legible para revisar y evita “cadenas misteriosas” más adelante.
Cuando uses la clave en un componente, incluye parámetros y lógica de plurales desde el primer día para que los traductores vean la forma completa del mensaje.
// simple param
$t('billing.invoiceDue', { date: formattedDate })
// plural
$t('files.selected', count, { count })
Si las traducciones no están listas, no dejes claves faltantes. Añade traducciones placeholder en otros locales o márcalas como pendientes de forma consistente (por ejemplo, prefija el valor con TODO:). Lo importante es que la app se renderice de forma predecible y los revisores puedan detectar copy sin terminar.
Antes de hacer merge, ejecuta comprobaciones automáticas rápidas. Manténlas aburridas y estrictas: claves faltantes entre locales, claves sin usar, desajuste de placeholders (falta {count}, {date} o llaves mal colocadas), formas plurales inválidas para los idiomas soportados y sobrescrituras accidentales.
Por último, haz un pequeño pase de UI en al menos un locale no base. Elige un idioma con cadenas más largas (a menudo alemán o francés) para captar desbordes, botones truncados y saltos de línea incómodos. Si tu UI Vue 3 se genera o mantiene junto a otras partes del producto (por ejemplo, una app web Vue3 producida por AppMaster), este paso sigue siendo importante porque los layouts cambian a medida que evolucionan las funcionalidades.
Trata estos pasos como tu definición de hecho para cualquier feature que añada texto.
Errores comunes que los equipos repiten
La forma más rápida de hacer la localización dolorosa es tratar las claves i18n como “solo cadenas”. Tras unas pocas centenas de claves, los hábitos pequeños se convierten en bugs en producción.
Claves que derivan, colisionan o mienten
Errores tipográficos y diferencias de casing son causas clásicas de texto faltante: checkout.title en un sitio, Checkout.title en otro. Parece correcto en la revisión de código y luego tu idioma de fallback se publica silenciosamente.
Otro problema común es reutilizar una clave para significados distintos. “Open” puede significar “Abrir ticket” en una pantalla de soporte y “Abrir ahora” en una tienda. Si reutilizas una sola clave, una de esas pantallas estará mal en otros idiomas y los traductores harán conjeturas.
Una regla simple ayuda: una clave equivale a un significado. Si el significado cambia, crea una clave nueva aun si el texto en inglés es igual.
Bugs de layout causados por suposiciones “en forma de cadena”
Los equipos a menudo hardcodean puntuación, espaciado o trozos de HTML en las traducciones. Eso funciona hasta que un idioma necesita distinta puntuación, o tu UI escapa o renderiza el marcado de forma diferente. Mantén las decisiones de marcado en las plantillas y mantén los mensajes centrados en el texto.
En móvil es donde los problemas se esconden. Una etiqueta que cabe en inglés puede envolver en tres líneas en alemán, o desbordarse en tailandés. Si solo pruebas un tamaño de pantalla, lo perderás.
Vigila a los reincidentes: asumir el orden de palabras en inglés al insertar variables (nombres, contadores, fechas), construir mensajes concatenando piezas en vez de usar un único mensaje, olvidar probar valores largos (nombres de producto, direcciones, detalles de error), publicar con fallback silencioso habilitado para que las claves faltantes parezcan “bien” en inglés, y copiar/pegar claves mientras se edita solo el valor en inglés.
Si quieres un flujo i18n en Vue 3 que se mantenga tranquilo con más de 500 claves, trata las claves como parte de tu API: estables, específicas y probadas como todo lo demás.
Pasos de QA que detectan traducciones faltantes temprano
Las traducciones faltantes son fáciles de pasar por alto porque la app sigue “funcionando”. Simplemente hace fallback a la clave, al locale equivocado o a una cadena vacía. Trata la cobertura de traducción como tests: quieres feedback rápido antes de que algo llegue a producción.
Comprobaciones automáticas (en cada PR)
Empieza con comprobaciones que fallen el build, no con advertencias que nadie lee.
- Escanea el código en busca de
$t('...')yt('...'), y verifica que cada clave usada exista en el locale base. - Compara conjuntos de claves entre locales y falla si algún locale tiene claves faltantes (a menos que la clave esté en una lista corta de excepciones revisada, como notas legales solo en
en). - Señala claves huérfanas que existen en archivos de locale pero nunca se usan.
- Valida la sintaxis de los mensajes (placeholders, bloques ICU/plural). Un único mensaje roto puede tirar una página en tiempo de ejecución.
- Trata claves duplicadas o casing inconsistente como errores.
Mantén la lista de excepciones corta y bajo la responsabilidad del equipo, no algo que “pase CI”.
Comprobaciones en tiempo de ejecución y visuales (staging)
Incluso con CI, quieres una red de seguridad en staging porque las rutas reales de usuario disparan cadenas que olvidaste que eran dinámicas.
Activa el logging de traducciones faltantes en staging e incluye suficiente contexto para arreglarlas rápido: locale, ruta, nombre del componente (si está disponible) y la clave faltante. Hazlo ruidoso. Si es fácil de ignorar, se ignorará.
Añade un pseudo-locale y úsalo para un pase rápido de UI. Un enfoque simple es transformar cada cadena (hacerla más larga y añadir marcadores) para que los problemas de layout salten, por ejemplo: [!!! 𝗧𝗲𝘅𝘁 𝗲𝘅𝗽𝗮𝗻𝗱𝗲𝗱 !!!]. Esto detecta botones cortados, cabeceras de tablas rotas y espacios faltantes antes de publicar.
Finalmente, haz una comprobación previa al lanzamiento de los flujos de mayor valor en 2-3 locales: inicio de sesión, checkout/pago, configuración principal y la nueva feature que vas a lanzar. Aquí es donde atrapas bugs como “se tradujo pero el placeholder está mal”.
Añadir idiomas nuevos y cambios continuos en el copy
Añadir un idioma nuevo se complica cuando lo tratas como “trabajo de copy” en vez de un pequeño lanzamiento de producto. La forma más fácil de mantener estable tu flujo i18n en Vue 3 es hacer que la app compile incluso cuando un locale está incompleto, pero dejando claras las lagunas antes de que los usuarios las vean.
Cuando añades un locale nuevo, empieza generando la misma estructura de archivos que tu locale fuente (a menudo en). No traduzcas primero, estructura primero.
- Crea la carpeta/archivo del nuevo locale con el conjunto completo de claves copiadas desde la fuente.
- Marca los valores como placeholders TODO para que las cadenas faltantes sean visibles en QA.
- Añade el locale al selector de idioma solo después de cubrir lo básico.
- Haz un pase pantalla por pantalla para detectar problemas de layout (palabras más largas, saltos de línea).
Las traducciones suelen llegar tarde, así que decide por adelantado qué significa “parcial” para tu producto. Si una feature es orientada al cliente, considera feature flags para que la funcionalidad y sus cadenas se publiquen juntas. Si debes lanzar sin traducciones completas, prefiere un fallback claro (como inglés) sobre etiquetas vacías, pero hazlo visible en staging.
Los cambios en el copy son donde los equipos rompen claves. Si cambias la redacción, mantén la clave estable. Las claves deben describir la intención, no la frase exacta. Reserva renombrar la clave para cuando cambia el significado, y aun entonces hazlo con una migración controlada.
Para evitar “cadenas zombi”, desaprueba claves a propósito: márcalas como deprecated con fecha y reemplazo, mantenlas un ciclo de releases y elimínalas solo después de confirmar que no hay referencias.
Mantén notas de traducción cerca de la clave. Si tu formato JSON no permite comentarios, guarda notas en un pequeño documento complementario o en un archivo de metadatos adyacente (por ejemplo, “usado en la pantalla de éxito del checkout”). Esto es especialmente útil cuando tu app web Vue 3 se genera desde una herramienta como AppMaster y varias personas tocan copy y UI.
Ejemplo: publicar una feature con 60 cadenas nuevas
En un sprint, tu equipo publica tres cosas a la vez: una nueva página de Settings, una pantalla de Billing y tres plantillas de correo (recibo, pago fallido, fin de prueba). Son unas 60 cadenas nuevas, y aquí es donde suele empezar el desorden i18n.
El equipo acuerda agrupar claves por feature y luego por superficie. Se crea un archivo nuevo para cada feature y las claves siguen el mismo patrón en todas partes: feature.area.element.
// settings
"settings.profile.title": "Profile",
"settings.security.mfa.enable": "Enable two-factor authentication",
// billing
"billing.plan.current": "Current plan",
"billing.invoice.count": "{count} invoice | {count} invoices",
// email
"email.receipt.subject": "Your receipt",
"email.payment_failed.cta": "Update payment method"
Antes de que empiece la traducción, las cadenas plurales se prueban con valores reales, no con conjeturas. Para billing.invoice.count, QA comprueba 0, 1, 2 y 5 usando datos iniciales (o un toggle dev simple). Esto detecta casos raros temprano, como “0 invoice”.
QA luego ejecuta un flujo enfocado que suele revelar claves faltantes: abrir Settings y Billing y hacer clic en cada pestaña una vez, disparar cada plantilla de correo en staging con cuentas de prueba, ejecutar la app con un locale no predeterminado activo y fallar el build si aparecen advertencias de traducciones faltantes en los logs.
En este sprint, QA encuentra dos claves faltantes: una etiqueta en Billing y un asunto de correo. El equipo las corrige antes del lanzamiento.
Al decidir si bloquear el lanzamiento o permitir fallback, usan una regla simple: pantallas orientadas al usuario y correos transaccionales bloquean el release; texto admin de bajo riesgo puede temporalmente hacer fallback al idioma por defecto, pero solo con un ticket y una fecha límite clara.
Próximos pasos y una lista de verificación simple para el lanzamiento
Un flujo i18n en Vue 3 se mantiene estable cuando tratas las traducciones como código: añádelas de la misma forma siempre, pruébalas y mide el resultado.
Lista de verificación de lanzamiento (5 minutos antes del merge)
- Claves: siguen el patrón de nombres y mantienen el alcance claro (página, feature, componente).
- Plurales: confirma que las formas plurales se renderizan correctamente en al menos un idioma con reglas plurales múltiples.
- Placeholders: verifica que las variables estén presentes, se llamen igual en todas partes y se vean bien con datos reales.
- Fallbacks: confirma que el comportamiento ante claves faltantes coincide con la política actual.
- Pantallas: revisa rápidamente las pantallas más propensas a romperse (tablas, toasts, modales, estados vacíos).
Decide qué medir (para que los problemas aparezcan temprano)
Elige unos pocos números simples y revísalos regularmente: tasa de claves faltantes en tu corrida de pruebas, número de cadenas sin traducir en locales no predeterminados y número de claves sin usar (cadenas que ya no aparecen en ningún sitio). Haz seguimiento por release si puedes, para ver tendencias en lugar de fallos aislados.
Escribe los pasos exactos para añadir una cadena, actualizar traducciones y verificar el resultado. Manténlo corto e incluye ejemplos de nombres de claves y uso de plurales. Los colaboradores nuevos deben poder seguirlo sin preguntar.
Si construyes herramientas internas, AppMaster (appmaster.io) puede ser una forma práctica de mantener el copy y las claves de traducción coherentes en una app web Vue3 y apps móviles complementarias, ya que todo se gestiona en un solo lugar.
Programa una pequeña tarea de salud i18n cada sprint: elimina claves muertas, corrige placeholders inconsistentes y revisa misses recientes. Las pequeñas limpiezas evitan cacerías de traducciones de emergencia en producción.


