Guías
Cuando algo falla
Empieza por npx verbaly doctor. Inspecciona el setup entero e imprime el arreglo exacto al lado de cada hallazgo, así que casi toda esta página es lo que te habría dicho él.
El comando verbaly no existe
El comando vive en @verbaly/compiler. Los plugins dependen de él, pero un gestor de paquetes solo enlaza el comando de un paquete que instalaste tú, así que no basta con que un plugin se lo traiga. Añádelo a tus dependencias de desarrollo:
Apareció un idioma que yo nunca pedí
Si no listas locales, cada archivo JSON de tu carpeta de catálogos cuenta como un idioma, salvo el del pseudo-idioma. Así que uno que dejó una ejecución anterior también lo es, y el build empieza a pedir sus traducciones. Lista tus idiomas y la lista queda completa:
Un aviso dice que un idioma no es un código válido
pt-BR es como se escribe un código de idioma, con un guion entre sus partes. pt_BR, como lo escriben gettext y muchos backends, no es un código que el navegador sepa leer, así que Verbaly lo lee como pt-BR para que números, fechas y plurales sigan formateándose, y avisa una vez de que lo hizo. Un código sin arreglo seguro se formatea en el idioma por defecto del navegador, con el mismo aviso. doctor nombra cada uno de tu config con su nuevo nombre: cambia el nombre del archivo del catálogo y tu config a la vez.
wrap reportó ficheros que no escribió
Un fichero donde t no está disponible se lista y se deja intacto, porque envolver texto ahí dejaría tu proyecto sin compilar. El informe dice cuántos textos esperan en cada uno y si es un componente de cliente, para que sepas qué línea añadir. Añádela y vuelve a ejecutarlo.
El build dice que una traducción está rota
No falta, está rota: la traducción está ahí y no puede renderizar lo que renderiza la fuente. Perdió un {value}, quitó un caso del plural o cambió una etiqueta. Cada build las lista primero, porque se renderizan mal, y npx verbaly check da la razón exacta de cada mensaje y falla con ellas en el CI.
El build compiló y luego listó traducciones
Ahí es donde corre la comprobación. En Next.js, next build compila tu app primero y luego lista las claves que faltan, las rotas y las desconocidas, así que los comandos que solo cargan tu config, como next typegen, nunca la corren. Completa lo que lista, o corre npx verbaly check antes del build para ver la misma lista antes. Con failOnMissing: true, el build se para ahí en su lugar.
Sale una key en pantalla en vez del texto
Un mensaje que no resuelve en ningún sitio se renderiza como su propia key. Normalmente el catálogo de ese idioma todavía no ha llegado, o el grupo es uno que excluiste del navegador con bundle.exclude y algo lo pide en runtime. El build avisa del segundo caso por su nombre. Si solo pasa en tu idioma fuente, lo más probable es que la key esté en una traducción y no en tu catálogo fuente: npx verbaly check la lista como una clave que solo tiene una traducción.
Mi edición en el catálogo fuente desapareció
Ese texto está escrito en tu código, con t`…` o t.id, así que es del código: el servidor de desarrollo, extract y el build vuelven a poner el texto del código. El mensaje dice qué archivo lo tiene, y ahí es donde se cambia. Si quieres editar un texto en el catálogo, deja solo su clave en el código, como t('key'). Desde la terminal, extract imprime una línea por cada texto que volvió a poner, con el texto que tenía, para que veas exactamente qué deshizo.
Una traducción aparece como desactualizada
Su texto fuente cambió después de que se escribiera, y nadie la ha tocado desde entonces. También puede aparecer justo después de un import: el archivo de un traductor trae el texto fuente del que partió, así que un archivo hecho para una versión anterior llega ya desactualizado. Actualiza la traducción y el aviso se va solo. Si sigue diciendo lo correcto, mantenla con npx verbaly review --approve. Nunca rompe un build salvo que tu CI corra check --outdated.
verbaly.lock tiene un conflicto de merge
verbaly.lock registra qué traducciones son borradores de la máquina y para qué texto fuente se escribió cada una. Cuando dos ramas tradujeron en paralelo, un merge puede dejarlo con un conflicto, y no hay lado que elegir: Verbaly lee los dos y conserva todos los borradores de cada uno. El siguiente extract escribe el archivo entero y lo avisa. Añádelo al commit que resuelve el merge.
Si el archivo sigue sin poder leerse (un conflicto editado a medias, por ejemplo), los comandos que solo lo leen avisan y siguen, y los que escribirían borradores se detienen antes de escribir nada. Arréglalo a mano y conserva las entradas de los dos lados: borrarlo, o quedarte con un solo lado, aprobaría borradores que nadie ha leído.
Un texto se queda en mi idioma fuente
El compilador solo lee las llamadas que se llaman t, así que de una función de traducción con otro nombre, como const tr = useT(), nunca se extrae el texto. extract y doctor nombran cada una con su archivo y línea, también en archivos .vue, .svelte y .astro: renómbrala a t. Si el archivo está fuera de tu include, tampoco se lee nada de él, y tu build y tu servidor de desarrollo lo nombran al arrancar, con el patrón que hay que añadir:
La página cambió de idioma justo después de cargar
La página llegó en un idioma y la instancia del navegador arrancó en otro, así que bindDom tradujo la página al suyo. Avisa una vez, nombrando los dos. Cuando la dirección lleva el idioma, crea la instancia con el locale que localeFromPath lee de ella; cuando no, llama primero a persistLocale, para que la página y el navegador partan de la misma elección.
Un mensaje muestra su código ICU en vez de su texto
La sintaxis ICU necesita su parser, y el compilador solo lo incluye cuando alguno de tus catálogos usa esa sintaxis en el build. Un mensaje que llega después, desde un CMS o con addMessages, no encuentra parser, así que muestra su propio código y avisa una vez. Pon icu: true en tu config de verbaly para incluir siempre el parser, o pasa icu a createVerbaly si creas la instancia tú.
Mis keys no están tipadas, o los tipos están viejos
Los tipos los escriben extract, los servidores de desarrollo y el build, así que un clon fresco o un job de CI no tiene ninguno hasta que corre uno de ellos: npx verbaly typegen los escribe solos, y es el arreglo de Cannot find module 'virtual:verbaly'. Van donde tu framework ya los lee, y un Cannot redeclare significa un verbaly.d.ts antiguo que quedó en la raíz, que la siguiente ejecución borra. Una errata en una clave falla con la clave en el error.
Prune dejó claves que ya no usas
Mientras algún archivo fuente no se pueda leer, extract --prune no quita nada y nombra el archivo. Un archivo que no puede leer puede ser justo el que usa esas claves, y podarlas entonces borraría sus traducciones. Arregla el error de sintaxis y vuelve a correrlo.
No se puede importar t desde verbaly
Ningún paquete exporta t. Sale del módulo propio de tu proyecto, virtual:verbaly, o del hook de tu framework. doctor reporta este como error porque ningún bundler puede resolverlo.