Saltar al contenido

Novedades

0.45.0

Última versión2026-08-28

Un catálogo solo crece, y todas las páginas pagaban el catálogo entero

El texto que vive en una sola página, una lista de versiones, un archivo de blog, una lista larga de preguntas, lo descargaba cada visitante en todas las páginas. Esta versión te deja nombrar esos grupos de mensajes y dejarlos en el build. Las páginas que los usan siguen saliendo traducidas, porque ese texto ya está escrito en el HTML, y el navegador deja de bajarlo. Buscar la prueba destapó además un defecto real por debajo. Tras su primera pasada, Verbaly podía sustituir texto traducido correcto de la página por el nombre interno del mensaje cuando ese mensaje faltaba. Queda arreglado aquí, y le importa a cualquiera que pre-renderice su sitio.

Destacados
  • El texto que solo necesita una página deja de viajar a todas. Nombra ese grupo de mensajes en tu configuración y el navegador ya no lo descarga. Las páginas que lo usan siguen saliendo traducidas, porque ese texto ya está en el HTML.
  • El texto pre-renderizado ya no se destruye. Si falta un mensaje, Verbaly conserva el texto que ya está en la página en vez de sustituirlo por el nombre interno del mensaje. Antes eso podía pasar un instante después de cargar la página.
  • Medido en este sitio: el fichero que carga cada página pasó de 46,3 KB a 33,5 KB comprimido, y los árboles en español y portugués bajaron unos 14 KB cada uno. No se perdió nada en pantalla.
  • Nada cambia si no lo activas. Es una opción nueva, y un proyecto que no la escriba se comporta exactamente igual que antes.
  • El build te avisa cuando algo pinta mal, nombrando un grupo que no coincide con nada de tu catálogo, o uno que tu código lee directamente.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.44.0

Versión2026-08-28

Nuestros propios chequeos medían la máquina, no el código

El job que comprueba nuestra cobertura de tests fallaba al azar, y la causa no era un test lento. Un test que tarda 22 milisegundos lo tumbaba un límite de 5 segundos, porque ese límite cuenta tiempo real y nuestro comando de tests levanta doce procesos sobre los mismos núcleos. Dos veces eso bloqueó una publicación. Esta versión lo arregla de raíz, y dedica el resto a la misma idea aplicada a nuestra cadena de suministro: qué puede hacer nuestro build, qué herramientas corre exactamente, y código que no podía ejecutarse nunca. Nada del paquete cambia.

Destacados
  • Nada de lo que instalas cambia. El runtime es idéntico al de la 0.43.0 y toda la API publicada se comporta igual. Esta versión va de la maquinaria que nos revisa.
  • Nuestro build dejó de fallar al azar. La suite podía tumbar un test perfectamente sano solo porque la máquina estaba ocupada, y dos veces eso bloqueó una publicación.
  • Cada herramienta que corre nuestro build está fijada a un commit exacto. Una etiqueta la puede mover quien la controla, pero un commit no, así que nada puede cambiar en silencio lo que construye tu paquete.
  • El job que publica las versiones pide permiso de escritura solo donde lo necesita, en vez de dárselo a todo el flujo.
  • El análisis estático corre en cada cambio, y su configuración vive ahora en nuestro repositorio, fijada y legible, en vez de ser un ajuste que solo veíamos nosotros.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.43.0

Versión2026-08-27

Todo lo que decimos de nosotros vuelve a ser cierto

El badge de nuestro README dice ~3KB desde el principio, mientras el runtime pesaba en realidad 3,68 KB. En vez de debilitar el claim, esta versión saca la última pieza que valía la pena sacar: el formato de tiempo relativo son 318 bytes que casi ninguna aplicación escribe, y ahora solo viaja cuando alguno de tus mensajes lo pide. El resto de la versión es la misma idea apuntada a todo lo demás que el proyecto dice de sí mismo.

Destacados
  • El runtime pesa 3,00 KB. El formato de tiempo relativo se suma a ICU como algo que solo viaja cuando alguno de tus mensajes lo usa de verdad, y no hay nada que tengas que configurar.
  • Un formateador que escribas tú ahora sabe para qué mensaje lo llamaron. Recibe el nombre del parámetro y la clave del mensaje, así que sus propios errores pueden decir dónde ocurrieron, cosa que antes no se podía.
  • La política de seguridad cubre los doce paquetes, no los siete que existían cuando se escribió, y ahora explica cómo verificar que una versión salió de verdad de nuestro CI.
  • Nuestra postura de seguridad es algo que puedes comprobar en vez de algo que afirmamos: una puntuación de la OpenSSF corre en cada cambio y el badge del README la lee.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.42.0

Versión2026-08-27

Un runtime más pequeño para quien nunca necesitó ICU

La sintaxis propia de Verbaly cubre plurales, selects y formatos, y la sintaxis ICU es la salida para lo que no cubre. Esa salida siempre se describió como algo opcional, y nunca lo fue: el parser entraba en toda aplicación usara ICU o no. Nuestro propio sitio de documentación no tiene ni un mensaje ICU y lo publicaba en cada página. Verbaly ya lee tus catálogos, así que ahora solo manda el parser donde algún mensaje lo necesita de verdad.

Destacados
  • El runtime es un 11% más pequeño para quien no usa sintaxis ICU, que son casi todos los proyectos. El parser solo viaja cuando alguno de tus mensajes lo necesita de verdad, y no hay nada que tengas que encender.
  • No cambia nada si sí usas ICU. Verbaly lo ve en tus catálogos y se lleva el parser, igual que antes.
  • Un mensaje que llega a tu aplicación después del build y usa ICU ahora muestra su propio texto y dice por qué, en vez de quedarse a medio renderizar en algo que parece casi correcto. Si tu texto viene de un CMS, un ajuste manda el parser igual.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.41.0

Versión2026-08-27

Una línea para cambiar, y tu elección por fin se queda

Verbaly traía un cambiador de idioma completo para una forma de hacer las direcciones y una pieza suelta para la otra, así que todo proyecto escribía la segunda a mano, el nuestro incluido. Reescribir nuestro propio sitio sobre el helper de la librería encontró un fallo que llevaba ahí desde que el cambiador entró en el runtime: quien elegía un idioma volvía al de su navegador en la siguiente carga. La otra mitad es que Verbaly había empezado a suponer que querías el idioma en tus direcciones; ahora lee tu montaje en vez de adivinar.

Destacados
  • Cambiar de idioma es una línea, y es la misma línea funcionen como funcionen tus direcciones. Va a la otra dirección cuando el idioma vive ahí, y cambia el texto donde está cuando no.
  • Tu elección de idioma sobrevive a la siguiente carga. Elegir inglés en una página en español podía devolverte al español, porque el cambio guardaba tu elección en un sitio y la página que te recibe leía otro.
  • Verbaly deja de suponer que quieres el idioma en tus direcciones. Lee tu montaje: si construyes una versión de tu sitio por idioma tienes direcciones por idioma, y si no, una sola sirve para todas. Solo lo escribes para llevar la contraria.
  • verbaly doctor te dice si leyó tu elección o la dedujo, para que un ajuste que nadie escribió no parezca una decisión que alguien tomó.
  • La comprobación de tamaño ahora mide lo que una aplicación real embarca de verdad, y no solo la importación más pequeña posible y la más grande imposible.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.40.0

Versión2026-08-27

Di dónde vive el idioma, y traduce también la cabecera

Verbaly lleva mucho con dos formas de cargar el idioma y nunca nombró ninguna, así que cuál te tocaba lo decidía si te acordabas de pasar un campo opcional. Nombrarlas destapó lo que hacía que nombrarlas importara: una página podía estar traducida en todo lo que un visitante mira y aun así decirle a un buscador que está en inglés, porque el título y la descripción viven en la cabecera, donde nadie los lee. Nuestra propia documentación publicaba 27 de 27 páginas así.

Destacados
  • Ahora puedes decir dónde vive el idioma en tus direcciones, una vez, en la configuración: /docs y /es/docs, un prefijo en todos los idiomas, o una sola dirección para todos. Antes la respuesta dependía de qué helper llamabas y qué le pasabas.
  • El selector de idioma es una línea y no se puede escribir mal. Verbaly te da un helper que ya conoce tus idiomas, tu fuente y tu modo, y la misma línea sigue funcionando si cambias de idea sobre el modo.
  • El título y la descripción de tus páginas también se traducen. Viven en la cabecera, nadie los lee en la página y son lo que enseña un resultado de búsqueda, así que una página podía parecer traducida entera y aparecer listada en inglés.
  • verbaly render cuenta las páginas cuyo título todavía no cambia nunca y te lo dice una vez, con el arreglo. Nunca tumba un build: el nombre de un producto puede no traducirse.
  • verbaly doctor te dice en qué modo están tus direcciones, y te avisa cuando tu configuración pide dos cosas que no pueden ser ciertas a la vez.
  • Breaking: pedir una ruta sin nombrar tu idioma fuente ya no compila. Antes ponía prefijo a todos los idiomas incluido el tuyo, en silencio, que casi nunca era lo que alguien quería.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.39.0

Versión2026-08-27

Traducir sobrevive a una mala conexión, y los agentes reciben el ciclo entero

Verbaly deja que un agente de código lo ejecute desde hace tiempo, pero de sus doce comandos solo cuatro llegaron a estar disponibles, y los dos que faltaban son los dos primeros que un agente necesita: averiguar qué falla en un proyecto y envolver el texto que ya está escrito en él. Mirando eso apareció algo peor al lado. verbaly translate es el único comando que cuesta dinero y minutos, y una sola respuesta mala tiraba la corrida entera: lotes ya pagados y traducidos nunca llegaban al disco.

Destacados
  • verbaly translate ya no pierde el trabajo que ya pagaste. Una petición que no vuelve se reintenta, y si aun así falla la corrida sigue y guarda todo lo demás. Volver a correrlo pide solo lo que falta, en vez de pagarlo todo otra vez.
  • Traducir es unas cuatro veces más rápido. Ahora las peticiones salen juntas en vez de una detrás de otra, y una corrida larga te va contando qué llegó mientras trabaja, en lugar de quedarse callada durante minutos.
  • Puedes decir qué no se traduce nunca. Pon los nombres de tu producto y cualquier forma que ya hayas decidido en translate.glossary, y cómo tratas al lector en translate.instructions, en vez de corregir la misma palabra a mano después de cada corrida.
  • Tu agente de código recibe las dos herramientas que le faltaban: una para averiguar por qué un proyecto no funciona, y otra para encontrar el texto escrito directamente en tus componentes y envolverlo. Llevar una aplicación existente a Verbaly ya no necesita una terminal.
  • Ahora los agentes leen números, no frases. Cada herramienta responde con datos simples además del texto, así que un agente deja de adivinar una redacción que puede cambiar entre versiones.
  • Aceptar una traducción automática sigue siendo algo que solo puede hacer una persona, y eso no ha cambiado.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.38.0

Versión2026-08-15

Las traducciones escritas por grupos ya son seguras en todas partes

Puedes guardar tus traducciones como grupos anidados en vez de una sola lista plana, y Verbaly lleva tiempo leyendo esa forma. Solo la leía la mitad: los comandos que escriben tus catálogos tomaban los nombres de grupo como si fueran mensajes. Así que extract añadía una segunda copia de cada mensaje, --prune borraba grupos enteros con todas las traducciones dentro, los exports llegaban rotos a tu traductor y translate decía que no había nada que hacer sobre una app a medio traducir. Para un catálogo plano no cambia nada.

Destacados
  • Las traducciones guardadas por grupos están a salvo de punta a punta. Ahora todos los comandos las leen y las escriben igual, y tu fichero conserva la forma que le diste en vez de quedar aplanado a tus espaldas.
  • verbaly extract --prune ya no borra traducciones. En un catálogo escrito por grupos leía el nombre de cada grupo como un mensaje, no lo reconocía y se llevaba el grupo entero con todas las traducciones dentro.
  • Tus ficheros para el traductor dejan de llegar rotos. El export escribía [object Object] donde tenía que ir el texto, y verbaly translate decía que no había nada que hacer mientras verbaly status decía que media app estaba sin traducir.
  • Un idioma que añadas después encaja con el resto. Un catálogo nuevo toma la forma de los que ya tienes, así que un proyecto nunca acaba medio por grupos y medio plano.
  • La herramienta cuenta en inglés de verdad. Antes decía 1 messages, 1 locales y 1 pages en nueve sitios.
  • Un aviso repetido se dice una sola vez. Una colisión de keys se anunciaba tres veces en un solo verbaly extract, una de ellas después de que el resumen ya se hubiera impreso.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.37.0

Versión2026-08-10

El idioma que guardaste sobrevive al F5

La versión anterior le puso nombre a las dos formas que tiene un sitio de llevar su idioma. Escribir la página que las explica destapó por qué una de ellas nunca había funcionado del todo: si tu app mantiene una sola dirección por página y carga los idiomas a demanda, Verbaly sabía qué idioma quería el visitante y sencillamente no lo pedía nunca. Una línea, y el ejemplo de nuestras propias docs lo venía enseñando desde siempre.

Destacados
  • El idioma guardado ya sobrevive a un F5 en un sitio de una sola dirección. Quien volvía recibía el idioma fuente otra vez, sin nada en la consola que lo explicara.
  • No cambia nada si tu idioma va en la dirección, que es de lo que iban las dos versiones anteriores. Esto solo estaba roto donde el idioma sale del almacenamiento o del navegador.
  • Un aviso que daba un consejo imposible ahora da el bueno. Cuando tu página dice un idioma y Verbaly está en otro, te decía que leyeras el idioma de la dirección. En un sitio de una sola dirección no hay nada que leer.
  • React, Vue y Svelte se probaron uno a uno contra un idioma que llega cuando la página ya está en pantalla. Antes era un camino raro y ahora es el normal.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.36.0

Versión2026-08-09

Tus visitantes llegan solos a su idioma

Verbaly publica tu sitio en cada idioma, cada uno en su propia dirección. La versión anterior dejó esas páginas bien, y esta va sobre cómo llega la gente hasta ellas, y sobre poder preguntar desde tu propio código a qué idioma pertenece una página. Las dos cosas las tenía que escribir a mano cada proyecto, este sitio dos veces en un día. También arregla una forma en la que el nombre de una página se podía confundir con un idioma.

Destacados
  • Preguntar en qué idioma está una página ya no necesita un ayudante tuyo. Verbaly responde con el idioma que dice la dirección, o con nada cuando la dirección no dice ninguno. Esa es una pregunta distinta a qué prefiere el visitante, y mezclar las dos es lo que dejaba que una preferencia guardada pintara el idioma equivocado sobre una página.
  • Verbaly ya puede mandar al visitante a su idioma. Lo activas y quien aterriza en tu página de inicio va a tu sitio en su idioma antes de que se dibuje nada. Solo la página de inicio, así que un buscador sigue llegando directo a cualquier página de tu sitio.
  • Un sitio servido desde una subcarpeta funciona. Le dices a Verbaly cuál es la carpeta y los enlaces dentro de cada idioma apuntan a donde deben, en vez de apuntar a la nada en silencio.
  • Una página llamada /es-la-guia es una página, no español. Verbaly leía el principio de una dirección con demasiadas ganas, así que una página cuyo nombre empezaba como un código de idioma se podía traducir a ese idioma. Ahora solo cuenta un código de idioma de verdad.
  • Lo que esta versión no cambia: una app con una sola dirección por página funciona exactamente igual que antes. Todo esto es para sitios donde cada idioma tiene su propia dirección.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.35.0

Versión2026-08-08

Tus páginas pre-traducidas dejan de parpadear

Verbaly publica tu sitio estático en cada idioma, bajo /es/ y /pt/. Esta versión va sobre lo que le pasaba a quien llegaba a una de esas páginas: llegaba en español y parpadeaba a inglés antes de volver, nada le decía al runtime que ya estaba en una página en español, y todos los enlaces apuntaban hacia fuera. La página estaba bien y todo lo que había entre ella y el visitante, no.

Destacados
  • Una página pre-traducida deja de parpadear a inglés. Verbaly servía la página en español y luego pintaba el texto en inglés encima hasta que terminaba de cargar el catálogo español, justo en las páginas que esta función existe para mantener quietas.
  • Aterrizar en /es/ ya es suficiente. Verbaly lee el prefijo que él mismo escribió antes de mirar el almacenamiento o el navegador, porque la página que estás viendo ya está en ese idioma.
  • Cada idioma deja de ser una isla. Sus enlaces apuntaban a la raíz del sitio, así que llegar en español y hacer un clic te devolvía al inglés. Los enlaces a páginas que ese idioma también tiene ahora se quedan dentro.
  • Tu selector de idioma lleva a tu sitio en ese idioma. Esa es la dirección que se puede compartir y la que indexan los buscadores, y la página llega ya traducida, así que no parpadea nada. En una app con una sola dirección por página, cambiar de idioma sigue cambiando solo el texto, igual que antes.
  • Lo que esta versión no hace: no enruta a nadie. Quien aterriza en tu raíz está recibiendo el idioma fuente, y mandarlo a su idioma es una regla en la configuración de tu hosting.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.34.0

Versión2026-08-08

Lo que el gate del build no puede ver

El gate del build se niega a compilar cuando una traducción no puede renderizar lo que renderiza tu fuente, pero solo ve lo que hay en tu proyecto al compilar. Esta versión va por todo lo que llega después: un catálogo que viene de un gestor de contenidos, un archivo de código que Verbaly no pudo leer y un salto de línea dentro de un mensaje con formato sobre el que la página pre-renderizada y el navegador no se ponían de acuerdo. Cuatro errores reales, cada uno una forma de publicar algo mal con todos los comandos en verde.

Destacados
  • Un salto de línea dentro de un mensaje con formato ya no se duplica en una página pre-renderizada. Verbaly lo escribía de una forma que los navegadores leen como dos saltos, y la página los reemplazaba por uno al cargar. Un salto visible, justo en las páginas que esa función existe para mantener quietas.
  • Una traducción que llega como null ya no tumba tu aplicación al arrancar. Un campo que nadie rellenó en un gestor de contenidos paraba todo antes del primer render. Ahora se salta esa clave, la aplicación funciona y la consola te dice cuál era.
  • Los comandos sobreviven a un archivo que no pueden leer. Un archivo con un error de sintaxis terminaba la ejecución entera con una posición y ningún nombre de archivo. Ahora se nombra el archivo, se saltan sus textos y el resto se sigue leyendo.
  • El texto dentro de JSX escrito en un archivo .js se encuentra igual que en cualquier otro sitio. Una aplicación React con componentes en .js no podía ni ejecutar el comando extract, porque la primera etiqueta lo terminaba.
  • Un aviso ya no se repite porque cambió un número. Tres de ellos imprimían el valor que los causaba, así que un contador subiendo podía llenar la memoria de copias del mismo mensaje.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.33.0

Versión2026-07-29

La API pública pasa a ser una decisión

El paquete del compilador te dejaba importar 132 cosas distintas, y ninguna estaba escrita en ningún sitio. Se habían ido acumulando como lo que los paquetes de framework fueran necesitando, y en la versión 1.0 cada una se habría convertido en una promesa que nadie había revisado nunca. Esta versión lee la lista entera contra una regla escrita, publica las 60 que la pasan, las documenta y añade un test que falla si la lista vuelve a crecer sin querer.

Destacados
  • Si usas la línea de comandos o cualquiera de los paquetes de framework, esta versión no te cambia nada. Ni configuración, ni imports, nada que editar. Todo lo de aquí pasa dentro de un paquete al que solo llegan las integraciones hechas a mano.
  • El paquete del compilador ya documenta qué puedes importar, en dos grupos: los tipos que necesitan tu archivo de configuración y tu propio proveedor de traducción, y las piezas para construir una integración que nosotros no publicamos. Todo lo demás es interno y ahora lo dice.
  • La lista pasó de 132 nombres a 60. Cada uno se quedó porque lo usa una integración real, porque es una forma documentada de extender Verbaly, o porque otro lo necesita. Los 72 que no cumplían ninguna de las tres ya no están.
  • Un plugin de build ya no recibe el árbol interno con el que Verbaly lee tu código. Antes le llegaba entero solo para leerle dos campos, y ahora recibe los mensajes que encontró. Una cosa menos que se puede romper cuando cambie ese lector.
  • Los dos paquetes fallan su propio test si la lista crece, así que añadir algo público es ahora una decisión que alguien revisa, en vez de algo que pasa de camino a arreglar otra cosa.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.32.0

Versión2026-07-29

Nada se rompe en silencio

Verbaly ya se negaba a compilar cuando una traducción no podía renderizar lo que renderiza tu fuente. Esta versión cierra la misma historia por el otro lado: cada sitio donde Verbaly hacía lo seguro sin decir nada ahora te avisa, en el momento en que puedes actuar. Un plural que renderiza una línea vacía, un precio sin moneda, un bloque escrito donde no puede funcionar y un nombre importado de donde no existe: cuatro formas de publicar el texto equivocado con todo en verde.

Destacados
  • Un plural sin caso comodín ahora avisa en el navegador, no solo en el build. La comprobación del build ya lo rechazaba, pero un catálogo que llega por carga diferida o desde un gestor de contenidos nunca pasa por el build, así que la línea vacía podía llegar a una página real. Ahora nombra el mensaje y te dice qué añadir.
  • Un hueco al que le falta su argumento deja de renderizar un número pelado. Un precio sin código de moneda, una medida sin unidad, una fecha sin unidad de tiempo: cada uno imprimía el valor plano y se callaba. Ahora cada uno dice qué necesita y te muestra la forma del arreglo.
  • Escribir un plural dentro de una plantilla t ya no se publica con las llaves a la vista. En esa plantilla los valores vienen de tu código, así que un plural o un formato escrito ahí se vuelve texto que ven tus usuarios. verbaly extract y verbaly doctor ahora señalan el archivo y el texto exacto.
  • Importar t del paquete por fin recibe una respuesta que menciona a Verbaly. t viene de tu instancia o del módulo generado, nunca del paquete, y hasta ahora solo se quejaba el bundler, con un mensaje que no daba ninguna pista de dónde debía salir t.
  • Cada error de la línea de comandos imprime su nombre una vez. Antes todo fallo se leía [verbaly] [verbaly].
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.31.0

Versión2026-07-28

La herramienta deja de contradecirse

Un comando decía que el proyecto estaba sano mientras otro bloqueaba su build por los mismos archivos. El doctor rechazaba los catálogos escritos como grupos anidados, aunque el runtime siempre los ha leído, y le decía a un proyecto Astro o Nuxt que instalara el paquete que el comando de setup le acababa de desaconsejar. El gate del build leía cualquier palabra entre signos de menor y mayor como markup, y tumbaba traducciones correctas por eso. Todo eso pasa a contar la misma historia: lo que un comando te dice es lo que tu proyecto es.

Destacados
  • verbaly doctor deja de contradecir a verbaly check. Una traducción que está pero está rota ahora también es un error en el doctor, así que el comando que corres cuando algo va mal ya no puede responder "el setup se ve sano" en un proyecto cuyo build falla.
  • Los catálogos escritos como grupos anidados funcionan en todas partes. El doctor los rechazaba como inválidos, y el gate solo comparaba los nombres de los grupos, así que un grupo con una línea sin traducir dentro contaba como traducido entero. Ahora cada línea se revisa por su cuenta, como el runtime ya la leía.
  • El doctor te señala el paquete que tu proyecto realmente necesita: Astro, Nuxt, Next.js, SvelteKit, Vite o el plugin de tu bundler. Es la misma respuesta que da verbaly init, porque los dos leen ahora una sola tabla.
  • El build deja de fallar por texto que solo parece markup. "Press <Enter> to continue" traducido como "Pulsa <Intro> para continuar" se reportaba como dos tags rotos. Un tag cuenta como estructura solo cuando el mensaje lo cierra, así que tu prosa sigue siendo prosa y un tag de énfasis o un enlace de verdad siguen protegidos.
  • Cada fallo nombra el paso que lo repara, en vez de un único "corre extract" que solo arreglaba las traducciones que faltaban. Y apagar la revisión de faltantes ahora significa lo que dice: puedes buildear con texto sin traducir, y Verbaly sigue negándose a publicar una traducción que renderiza mal.
  • Un valor que falta dice de qué mensaje viene. El aviso imprimía solo el nombre del placeholder, una vez por nombre, así que el segundo mensaje con el mismo hueco se quedaba callado.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.30.0

Versión2026-07-28

El gate del build deja de confiar en una traducción llena

Hasta ahora el check hacía una sola pregunta: ¿hay un valor para cada key? Una traducción podía dejar afuera tu placeholder de nombre, perder un tag de énfasis o aplanar un bloque de plural, y el build seguía en verde mientras producción mostraba en silencio el texto equivocado, o nada. Ahora el gate lee cada traducción contra su original y falla ante todo lo que no la puede mostrar, con el motivo en palabras simples y la línea del fuente para hacer clic. El runtime deja de callarse el mismo tipo de bug, y el paquete de React queda verificado contra Preact.

Destacados
  • El build ahora caza traducciones que están pero están rotas. Un placeholder que falta, un tag perdido, un bloque de plural convertido en texto plano, o un plural sin caso comodín: cada uno detiene el build con una frase que dice qué pasó y por qué importa. Antes de esto, un catálogo editado a mano no tenía ninguna revisión.
  • El bug del texto vacío se fue. Un bloque de plural que perdía su caso comodín no mostraba nada para cada cantidad que no listaba. En polaco, un mensaje con solo "one" y "few" mostraba una cadena vacía para 5 elementos. Eso ahora falla el build en vez de publicarse.
  • Verbaly le dice a quien traduce qué formas plurales necesita de verdad su idioma. Un catálogo polaco o ruso con solo dos formas recibe una advertencia que nombra las que faltan. Es un consejo, no un fallo: el texto igual se muestra. Las formas que ningún contador real alcanza nunca se piden, así que el español, el francés, el portugués y el italiano quedan en silencio.
  • verbaly status muestra un conteo de roto por idioma, así ves el estado de un catálogo sin correr el gate.
  • Un valor que falta ahora avisa en la consola. Mostrar un placeholder crudo porque nadie pasó el valor era el único caso de dato malo que Verbaly no reportaba. Todos los demás ya lo hacían.
  • Preact funciona, y ahora está probado. El paquete de React corre su suite completa una segunda vez con React resuelto a preact/compat: hooks, cambio de idioma, texto rico y render en servidor pasan todos. Sin paquete aparte y sin cambios en tu código.
  • VS Code puede mostrar tus traducciones al pasar el mouse. El README del repositorio trae la configuración de i18n-ally que convierte las keys con hash en texto legible mientras programas.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.29.0

Versión2026-07-27

Tu agente de código ya puede correr todo el ciclo de traducción

Un nuevo servidor MCP le da a Claude Code, Cursor y cualquier cliente MCP cuatro herramientas: ver la cobertura, listar lo que falta, extraer texto nuevo y traducir los huecos a máquina. Todo lo que el agente traduce sigue esperando tu revisión. Una Agent Skill pública y un llms.txt en la documentación completan el canal, los proyectos Nuxt mantienen su raíz limpia y los fragmentos de código que solo se muestran ya no pueden volverse claves fantasma.

Destacados
  • El ciclo de traducción como herramientas de agente. Un comando (claude mcp add verbaly -- npx -y @verbaly/mcp) y tu agente de código puede revisar la cobertura, listar traducciones faltantes, extraer texto nuevo y llenar los huecos con traducción máquina. Lo que traduzca se guarda como borrador, así que nada se publica sin que una persona diga que sí.
  • Una Agent Skill pública le enseña Verbaly a tu agente. Instala skills/verbaly del repositorio en tu proyecto y el agente conoce el ciclo de escribir, extraer, verificar y traducir, y las reglas que lo mantienen seguro.
  • La documentación ahora habla LLM. Este sitio publica un índice llms.txt, así los agentes que leen documentación se ubican en Verbaly sin raspar HTML.
  • Los proyectos Nuxt mantienen su raíz limpia. Los tipos generados ahora viven dentro de .nuxt/ y se registran solos, igual que ya lo hacía la integración de Astro. Ningún archivo en la raíz del proyecto y ningún cambio en tsconfig.
  • El código que solo se muestra ya no puede volverse una clave de traducción. Las páginas que enseñan ejemplos de t como texto visible en archivos Vue, Astro o Svelte corrían el riesgo de que esos fragmentos se extrajeran como claves reales. Ahora solo cuenta el código dentro de expresiones de verdad.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.28.0

Versión2026-07-20

Gettext PO, placeholders protegidos y un runtime más sólido

El kit para traductores está completo: exporta e importa archivos gettext PO, y XLIFF ahora protege tus placeholders y tags para que un traductor no pueda romperlos por accidente. El nombre custom del sitemap en render por fin funciona, un crash raro con fechas inválidas desapareció, y el runtime ya no puede crecer en silencio por encima de su presupuesto de tamaño.

Destacados
  • Exporta e importa archivos gettext PO. verbaly export --format po escribe un archivo .po por idioma, listo para Poedit, Weblate o cualquier editor PO. verbaly import los lee de vuelta con la misma red de seguridad que todos los formatos: una traducción que rompe un placeholder se rechaza, no se publica. Las entradas que una herramienta marca como fuzzy cuentan como sin traducir.
  • Los traductores ya no pueden romper tus placeholders en XLIFF. Placeholders y tags viajan como códigos protegidos con nombres con sentido, así que las herramientas de traducción los muestran como fichas intocables en vez de texto editable. Las palabras de plural y select siguen editables a propósito: esas sí se traducen.
  • Los nombres custom de sitemap ya funcionan. Configurar un nombre propio para el sitemap en render se ignoraba: siempre escribía sitemap-i18n.xml. El nombre que configuras es el nombre que obtienes.
  • Un crash raro desapareció. Pasar una fecha inválida a un mensaje podía lanzar un error en vez de degradar con gracia. Lo encontró una suite nueva de tests aleatorios que castiga al parser con basura en cada corrida, así que esta clase de bug se queda arreglada.
  • El runtime ya no puede crecer en silencio. Cada push mide el bundle del core y falla si supera su presupuesto de tamaño. La promesa de ~3 KB la hace cumplir una máquina, no una costumbre.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.27.0

Versión2026-07-19

Traducciones a máquina que revisas antes de confiar

Las traducciones a máquina ahora llegan como borradores que revisas, no como trabajo terminado en el que confías a ciegas. Un comando nuevo las aprueba, el gate de CI puede esperar a un humano, y el modelo traduce con contexto de tu código.

Destacados
  • La salida de la máquina es un borrador hasta que digas lo contrario. verbaly translate sigue llenando los huecos, pero todo lo que escribe queda marcado como borrador sin revisar. Tus catálogos quedan tan limpios como antes: el estado de revisión vive en un archivo .verbaly-drafts.json aparte, junto a ellos.
  • Aprueba las traducciones cuando las hayas leído. verbaly review lista todo lo que espera a un humano; verbaly review --approve lo acepta, todo o un idioma a la vez. Importar el archivo de un traductor también cuenta como revisión, así que la marca de borrador se limpia sola.
  • Bloquea merges con texto de máquina sin revisar. verbaly check --drafts hace fallar el CI mientras quede alguna traducción a máquina sin revisar. El verbaly check normal no cambia, así que nada se rompe hasta que decidas activarlo.
  • Mejores traducciones, porque el modelo recibe contexto. verbaly translate ahora le dice al provider en qué archivos fuente aparece cada texto, así el tono y el largo encajan donde el texto se usa.
  • Mira qué falta revisar de un vistazo. verbaly status (y --json) ahora reportan cuántos borradores sin revisar hay por idioma.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.26.0

Versión2026-07-18

Soporte para Astro, un codemod wrap y anotaciones en CI

Astro se une a la familia: una línea conecta todo y el rendering por idioma corre solo. Un nuevo comando wrap envuelve tu texto JSX hardcodeado por ti, y los fallos de CI se vuelven anotaciones directamente en tus pull requests.

Destacados
  • Soporte para Astro, una línea. Agrega verbaly() a las integrations de astro.config y todo queda conectado: extracción en vivo mientras programas, claves type-safe y el gate del build. Las claves tipadas viven dentro de la carpeta .astro propia de Astro, así que ningún archivo extra aterriza en tu proyecto. En el flujo de espejo, verbaly render corre solo después de cada build.
  • Escribe tu texto directamente en archivos .astro. El mismo t`…` que ya usas en .js, .tsx, .svelte y .vue ahora funciona en el frontmatter y el markup de los componentes Astro.
  • ¿Migrando una app existente? Deja que verbaly wrap haga la parte aburrida. Escanea tu JSX, encuentra el texto visible hardcodeado y lo envuelve en t`…` por ti. Primero reporta; nada se toca hasta que pases --write.
  • Los fallos de CI ahora apuntan a tu código. verbaly check --reporter github convierte cada traducción faltante en una anotación sobre el archivo y la línea exactos, directamente en el pull request.
  • verbaly status --json te da los números de cobertura en formato machine-readable, listos para badges y dashboards.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.25.0

Versión2026-07-18

RTL automático, nombres de idioma reales y contexto para traductores

Agregar árabe o hebreo ahora simplemente funciona: la dirección de la página sigue al idioma en todas partes. Los selectores de idioma reciben nombres reales de la plataforma, y los archivos de traducción dicen dónde vive cada texto.

Destacados
  • Los idiomas de derecha a izquierda simplemente funcionan. Agrega árabe, hebreo o persa y la dirección de la página sigue al idioma por su cuenta: cuando el usuario cambia, cuando el servidor renderiza y en las páginas estáticas pre-renderizadas. Sin atributo dir que administrar, nunca.
  • Selectores de idioma sin nombres hardcodeados. localeName('es') devuelve 'español' y localeName('de', 'en') devuelve 'German'. Los nombres vienen de la plataforma, así que cualquier locale funciona sin mantener una tabla.
  • ¿Necesitas la dirección tú mismo? localeDirection('ar') devuelve rtl. Es el mismo helper que usa el resto del toolkit, exportado para tus propios layouts.
  • Los traductores ahora ven dónde vive cada texto. verbaly export marca cada mensaje con los archivos fuente de donde viene: XLIFF recibe notas de ubicación estándar y CSV una columna de ubicación, así que el contexto deja de ser adivinanza.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.24.0

Versión2026-07-16

Llaves literales y páginas pre-renderizadas más seguras

Los mensajes rich por fin pueden mostrar una llave literal, y las páginas pre-renderizadas con verbaly render aplican las mismas reglas de seguridad que el navegador.

Destacados
  • Los mensajes ya pueden mostrar llaves literales. Escribe &#123; y &#125; en un mensaje rich y se renderizan como { y }. Las formas hex como &#x7B; también funcionan, en el navegador, en cada <Trans> y en páginas pre-renderizadas.
  • Las páginas pre-renderizadas son ahora tan seguras como el navegador. Los atributos traducidos pasan por los mismos guards, así que los links inseguros y los atributos peligrosos de un catálogo nunca llegan al HTML estático.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.23.0

Versión2026-07-14

Un <Trans> para todo, extracción en vivo y una vista de cobertura

Los componentes <Trans> de React, Vue y Svelte ahora comparten las mismas props y las mismas reglas de render, el CLI aprende dos comandos de uso diario y los últimos breaking changes planeados llegan antes de 1.0.

Destacados
  • <Trans> ya es el mismo componente en React, Vue y Svelte: mismas props, mismas reglas de render. Tu componente propio gana, luego los links nombrados, luego la whitelist segura de tags; lo desconocido degrada a texto plano.
  • Breaking: los <Trans> de React y Vue ahora renderizan tags whitelisteados como em y code como elementos reales, igual que Svelte y el intérprete de DOM. Pasa una lista richTags vacía para mantener el comportamiento anterior de aplanar a texto.
  • Breaking: @verbaly/svelte ahora requiere Svelte 5. A cambio <Trans> gana la prop components: mapea un tag del mensaje a tu propio componente. En Svelte 4, quédate en 0.22.0.
  • verbaly status muestra cuánto falta por traducir, una línea por idioma, sin hacer fallar nada. verbaly check sigue siendo el gate del build.
  • verbaly extract --watch mantiene catálogos y tipos al día mientras escribes código, pensado para setups de webpack, Rspack y Rollup donde el plugin de Vite no está disponible.
  • Dar feedback es más fácil: el README lleva los reportes de bugs y de fricción al lugar correcto, y los formularios de issues cubren los diez paquetes.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.22.0

Versión2026-07-14

Tus catálogos se vuelven recursos nativos de mobile

El comando export aprende dos formatos mobile: carpetas de recursos de Android y archivos de strings de iOS. Una app web y su companion mobile ya pueden compartir un solo set de traducciones.

Destacados
  • Exporta tus traducciones para apps mobile: verbaly export --format android-xml escribe carpetas que puedes soltar en res/, y --format ios-strings escribe carpetas .lproj para Xcode.
  • Defaults sensatos por plataforma: tu idioma fuente se vuelve el default de la plataforma, y las keys sin traducir se omiten para que la app caiga en él en vez de mostrar texto vacío.
  • Catálogos más seguros: un catálogo con JSON roto ahora detiene el comando y nombra el archivo, en vez de leerse en silencio como vacío. Un BOM de Windows al inicio del archivo simplemente se tolera.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.21.0

Versión2026-07-14

Un pase de calidad, y config de Nuxt tipada

Una limpieza a fondo de los diez paquetes, más opciones totalmente tipadas en tu config de Nuxt. Los internos quedaron más ordenados y un poco más pequeños, sin cambiar cómo escribes Verbaly.

Destacados
  • La key verbaly de nuxt.config.ts ahora está totalmente tipada: tienes autocompletado y detección de typos, y el módulo sigue sin sumar dependencias.
  • Un editor más tranquilo en dev. verbaly.d.ts solo se reescribe cuando su contenido realmente cambia, así tu servidor de TypeScript deja de recargar tipos en cada guardado.
  • Un runtime un poco más pequeño: el core tree-shaken ahora pesa 3.28 KB gzip, antes 3.30.
  • Tipos generados más limpios: un valor usado como fecha y como texto plano ya no aparece dos veces en verbaly.d.ts.
  • Mensajes del CLI más claros. Cada error y sugerencia se lee en palabras llanas, y check ahora imprime el texto fuente justo al lado de la key faltante.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.20.0

Versión2026-07-13

Escribe tu texto también en archivos .svelte y .vue

El texto natural ya funciona dentro de componentes Svelte y Vue: escríbelo en el archivo, script o markup, y el compilador lo extrae con key estable y params tipados.

Destacados
  • Escribe t`Hello ${name}` directamente en un template .vue o {$t`Hello ${name}`} en markup .svelte. El compilador lo detecta como siempre lo hizo en archivos .ts: key estable, params tipados, catálogos por idioma.
  • La forma store de Svelte se entiende: $t`…`, $t('key') y $t.id('key')`…` funcionan en cualquier parte de un archivo .svelte.
  • En vivo en dev, con gate en build: guarda un componente con texto nuevo y los catálogos más verbaly.d.ts se actualizan al instante. Las traducciones faltantes siguen deteniendo el build.
  • Las keys legibles y las keys de runtime también funcionan en markup: t.id('home.title')`…` extrae bajo tu key, y las llamadas t('key') cuentan como keys usadas para check y prune.
  • verbaly extract escanea más por defecto: archivos .svelte y .vue, más la carpeta app/ junto a src/ (donde viven Nuxt 4 y el App Router de Next.js). Tu propio include sigue ganando.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.19.0

Versión2026-07-13

Next.js se une a la familia: el ciclo está completo

La última gran integración de meta-framework. Las páginas del App Router de Next.js se renderizan ya traducidas, hidratan sin flash y funcionan en Turbopack y webpack.

Destacados
  • Nuevo paquete @verbaly/next. Dos pasos: envuelve tu config con withVerbaly() en next.config.ts y suelta <VerbalyProvider> en el layout raíz. Los Server Components traducen con await getT(); los Client Components siguen usando useT y <Trans> como en cualquier app React.
  • Funciona en Turbopack (el default de Next 16) y en webpack. next dev extrae tus mensajes mientras escribes, y next build se detiene si falta una traducción.
  • Cada visitante recibe su propio idioma, resuelto una vez por request desde su cookie o las preferencias del navegador. Las páginas llegan ya traducidas, nada parpadea, y los visitantes concurrentes nunca ven el idioma de otro.
  • useSwitchLocale() cambia el idioma al instante, recuerda la elección para la próxima visita y actualiza también los Server Components.
  • Los mensajes rich ya pueden mostrar markup literal, así un mensaje puede enseñar "<html lang>" como texto visible en vez de un escape roto.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.18.0

Versión2026-07-13

Nuxt se une a la familia

La segunda integración de meta-framework: un módulo de Nuxt sin config renderiza cada página en el idioma del visitante e hidrata sin flash.

Destacados
  • Nuevo paquete @verbaly/nuxt. Una línea en tu config (modules: ['@verbaly/nuxt']) conecta todo: extracción en vivo, idioma por visitante e hidratación con el mismo locale y catálogo que usó el servidor. Sin flash, sin mismatch.
  • Sin lock del framework: el módulo no depende ni de nuxt ni de @nuxt/kit, y está verificado contra una app Nuxt 4 real.
  • switchLocale() ahora es un export del core compartido por SvelteKit, Nuxt y setups a mano. Carga el catálogo primero y cambia después, así nada parpadea. Los imports existentes siguen funcionando.
  • Las apps client-only también están cubiertas: con ssr: false el módulo igual elige el idioma correcto en el navegador.
  • Apoya a Verbaly: GitHub Sponsors ya está activo en github.com/sponsors/AronSoto.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.17.0

Versión2026-07-11

Robusto por dentro, de verdad

La release de hardening: una auditoría completa de los ocho paquetes corrigió cada borde afilado que encontró, y SSR gana su pieza faltante.

Destacados
  • La traducción de atributos ahora es XSS-safe de punta a punta: data-verbaly-attr sanitiza atributos de URL y bloquea style y srcdoc por completo, así un catálogo comprometido no puede inyectar scripts.
  • t() nunca crashea por argumentos de formato malos: un código de moneda, fecha o estilo de hora inválido avisa una vez y renderiza el valor plano.
  • createRequestInstance(locale) en virtual:verbaly: el patrón SSR per-request en una llamada, con el catálogo ya cargado y sin flash.
  • El CLI ahora rechaza flags mal puestas. verbaly translate --locale es antes traducía todos los idiomas en silencio; ahora da error y sugiere --locales. Además --dry-run para extract --prune.
  • normalizeLink() y resolveRequestLocale() ahora viven una sola vez en el core, compartidos por cada adapter e integración SSR.
  • Breaking: instance.inspect(key) ahora devuelve { from, source } en lugar de { locale, source }: un solo nombre para un solo concepto en toda la API de observabilidad.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.16.0

Versión2026-07-11

Server-side rendering, de verdad

La primera integración de meta-framework: las páginas de SvelteKit se renderizan en el idioma del visitante en el servidor e hidratan sin flash.

Destacados
  • Nuevo paquete @verbaly/sveltekit. SSR en tres cables: verbalyHandle() en tus hooks de servidor, un load de +layout y %verbaly.lang% en app.html. Las páginas llegan traducidas.
  • El idioma se decide por request: cookie primero, luego el header Accept-Language (es-PE matchea es), luego tu fallback. Los requests concurrentes nunca filtran el idioma de otro.
  • switchLocale(): un switch client-side que carga el catálogo primero y luego guarda la elección en la cookie que el servidor lee.
  • negotiateLocale() en el core: el matcher de Accept-Language es un export público que cualquier servidor Node puede usar.
  • createInstance() en virtual:verbaly: instancias frescas por request sobre tus catálogos compilados, más los exports locales y sourceLocale.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.15.0

Versión2026-07-10

Tus traductores ya pueden trabajar

El ciclo write→ship se abre a humanos: exporta archivos listos para traductores, impórtalos de vuelta validados.

Destacados
  • verbaly export escribe un archivo listo para traductores por idioma: XLIFF 2.0 para plataformas de traducción, CSV para hojas de cálculo. --missing exporta solo lo que falta por traducir.
  • verbaly import valida cada entrada: una traducción que pierde un placeholder, una variante o un tag se rechaza y se reporta.
  • Las traducciones existentes se conservan salvo que pases --overwrite, y --dry-run previsualiza el import completo.
  • No necesitas plataforma de traducción: los catálogos son JSON plano, y Crowdin, Lokalise y Phrase lo leen nativo.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.14.5

Versión2026-07-10

Revisión de 0.14.0: la release de repaso

Una auditoría dura de lo que envió 0.14.0 encontró tres defectos reales. Todos corregidos aquí.

Destacados
  • El overlay de verbaly/devtools ya no congela la página: su observer ahora ignora sus propias escrituras.
  • &quot;&quot; ahora significa sin traducir en todas partes: el runtime cae al fallback en vez de renderizar un hueco en blanco.
  • Los mirrors por idioma reciben rel=&quot;canonical&quot; y og:url auto-canónicos, así el set de hreflang por fin cuenta.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.14.0

Versión2026-07-10

Sale traducido, y puedes ver por qué

SEO multi-idioma para el renderer estático, observabilidad del runtime, uso server-side endurecido.

Destacados
  • verbaly render emite alternates hreflang recíprocos y un sitemap i18n: define render.baseUrl y listo.
  • verbaly/devtools opt-in: pasa el cursor por cualquier elemento para ver su key, estado e idioma de origen.
  • Nuevo hook onResolve + inspect(key), con costo cero cuando no se usan.
  • El uso server-side en Node quedó endurecido y fijado con tests.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.13.1

Versión2026-07-10

README renovado: legible en el modo oscuro de npm

Patch solo de docs; primera release publicada desde CI con npm provenance.

Destacados
  • Los siete READMEs de paquete se leen bien en el tema oscuro de npm y son más fáciles de escanear.
  • MIT re-afirmado; las releases ahora salen con npm provenance desde el workflow automático.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.13.0

Versión2026-07-09

verbaly doctor + adopción y confianza

Un comando responde "¿por qué esto no traduce?", y una ruta real para salir de i18next.

Destacados
  • verbaly doctor inspecciona config, catálogos, cableado del plugin, tipos viejos y keys huérfanas, y le da a cada hallazgo su fix exacto.
  • Nueva guía Migrar desde i18next: conserva tus keys y tu JSON, cambia el runtime página por página.
  • La publicación pasa a GitHub Actions con npm provenance: cada paquete queda vinculado públicamente a su commit.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.12.0

Versión2026-07-09

verbaly init + el toolchain de TypeScript 7

De cero a traducir en un comando; el build pasa a tsdown y TS 7 nativo.

Destacados
  • verbaly init genera config + catálogos y detecta tu bundler. Nunca sobrescribe.
  • Toolchain: tsup → tsdown; typecheck en TypeScript 7 nativo (~10× más rápido). Sin cambio visible para el consumidor.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.11.0

Versión2026-07-08

Links rich + toda la superficie moderna de Intl

Links nombrados con hrefs que nunca salen de los catálogos, y los últimos formatters de Intl que faltaban.

Destacados
  • Los links nombrados en mensajes rich renderizan elementos <a> reales. El href sale de tu código, nunca del catálogo, y los schemes inseguros se bloquean.
  • Tiempo relativo ({when:relative}), listas ({xs:list}) y unidades CLDR ({n:unit/kilometer}): todo Intl nativo, cero dependencias.
  • Licencia: Apache-2.0 → MIT en los siete paquetes.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.10.0

Versión2026-07-07

Los sitios estáticos salen traducidos + Verbaly más allá de Vite

El FOUC muere en SSG, y webpack/Rollup/esbuild/Rspack se suman vía unplugin.

Destacados
  • verbaly render pre-llena tu HTML compilado por idioma con el runtime real, así las páginas estáticas salen ya traducidas.
  • Nuevo @verbaly/unplugin: los mismos módulos virtuales + gate de build en webpack 5, Rollup, esbuild y Rspack.
  • verbaly pseudo: un idioma de QA (⟦Ĥéĺĺó ~⟧) que expone strings hardcodeados y layouts recortados.
  • <Trans> llega a Svelte.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.9.0

Versión2026-07-06

La traducción automática cierra el ciclo

write → extract → translate → check en verde: el ciclo completo en una sola herramienta.

Destacados
  • verbaly translate llena los huecos &quot;&quot; que reporta check: por lotes, con --dry-run y filtros por idioma.
  • Validación estructural: placeholders, variantes y tags deben sobrevivir intactos o la traducción se rechaza.
  • Providers conectables: Claude como referencia, y cualquier función (messages) => translations funciona. Cero impacto en runtime.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.8.0

Versión2026-07-06

Keys legibles + catálogos lazy

Ids legibles cuando los quieres, carga lazy por idioma cuando la necesitas.

Destacados
  • t.id('inbox.title')`Hello ${name}`: keys legibles con namespace; el hash sigue siendo el default sin config.
  • loaders en createVerbaly: empaqueta solo el idioma fuente y carga el resto bajo demanda, sin flash con await loadLocale.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.7.0

Versión2026-07-04

Svelte se une al ecosistema

Stores idiomáticos sobre el mismo core reactivo, para Svelte 4 y 5.

Destacados
  • @verbaly/svelte: $t('key') se re-renderiza al cambiar de idioma, y bind:value={$locale} simplemente funciona.
  • Contexto vía provideVerbaly/useVerbaly o factories de stores sin árbol de componentes.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.6.0

Versión2026-07-04

El compilador entiende todo tu codebase

Escribe JSX en su lugar y el compilador lo extrae.

Destacados
  • Extracción write-in-place de <Trans>: el texto fuente con elementos reales se vuelve key + components automáticamente.
  • Soporte de verbaly.config.ts / .mts (esbuild como peer opcional).
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.5.0

Versión2026-07-04

Hardening + performance, con recibos

Los benchmarks vs i18next corren en cada release de aquí en adelante.

Destacados
  • Hot path memoizado de punta a punta: lookup 31×, interpolación 10×, plurales vs i18next.
  • Auditoría de defensa: cadenas de fallback cacheadas, args de DOM por elemento, caché de AST con tope.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.4.0

Versión2026-07-04

El intérprete de DOM se pone al día

Texto rich en HTML plano, con seguridad, más helpers de bootstrap del idioma.

Destacados
  • data-verbaly-rich: los mensajes con tags renderizan elementos reales desde una whitelist de phrasing, nunca innerHTML.
  • resolveLocale / persistLocale: storage → navigator → fallback, SSR-safe.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.3.0

Versión2026-07-03

Escape-hatch de ICU + robustez

Trae tus strings ICU: se detectan solos, cero dependencias.

Destacados
  • ICU MessageFormat (plural, select, selectordinal) parsea al mismo motor, opt-in por mensaje.
  • Tokenizer de <Trans> endurecido + avisos de colisión de keys en build.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.2.0

Versión2026-07-03

Ecosistema público + texto rich

Primera publicación en npm de los paquetes del ecosistema.

Destacados
  • @verbaly/compiler, @verbaly/vite, @verbaly/react y @verbaly/vue llegan a npm, con versión alineada.
  • <Trans> en React y Vue: interpola elementos dentro de frases traducidas con tags nombrados.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.

0.1.0

Versión2026-07-02

La primera release

La idea central, funcionando: escribe texto, envía traducciones.

Destacados
  • Runtime: formato de mensajes sobre Intl nativo, store de idioma reactivo, intérprete de DOM, keys y params a nivel de tipos.
  • Compilador: extracción por AST de t`…` a keys hasheadas estables, extract/check, verbaly.d.ts tipado.
  • Plugin de Vite: extracción en vivo, HMR, code-splitting por idioma, el build falla con traducciones faltantes.
Notas completas de la versiónCada detalle, por paquete, en el changelog del repo.
Copiado en el portapapeles