Conversor gratuito de HTML a JSX/React

Convierte HTML en JSX compatible con React automáticamente. Gestiona class→className, for→htmlFor, objetos style, gestores de eventos, etiquetas autocerradas y mucho más.

Entrada y salida

Opciones

Cómo funciona

  1. Pega HTML: introduce un fragmento HTML estándar (divs, formularios, tablas o bloques completos) en la zona de entrada.
  2. Elige las opciones: activa el envoltorio React Fragment y el formato pretty-print según necesites.
  3. Obtén el JSX al instante: el convertidor transforma automáticamente classclassName, forhtmlFor, las cadenas style en objetos style, y cierra las etiquetas autocerradas.
  4. Copia en tu proyecto: pega la salida JSX directamente en tus componentes React.

¿Por qué usar HTML → JSX?

Al migrar plantillas HTML a React, la conversión manual es propensa a errores. Olvidar un solo className o dejar una etiqueta sin cerrar rompe el build. Este convertidor gestiona automáticamente todos los cambios requeridos, incluida la conversión de nombres de propiedades CSS como background-color a camelCase backgroundColor en los atributos style, la transformación de cadenas de gestores de eventos en referencias a funciones y el cierre correcto de los elementos void. Esto acelera el prototipado, las migraciones de código y ayuda a los desarrolladores poco familiarizados con las diferencias de sintaxis JSX.

Conversiones clave

  • class → className: requerido en los componentes de React
  • for → htmlFor: para los elementos label
  • cadenas style → objetos: p. ej.: "color:red"{color:'red'}
  • Etiquetas autocerradas: <br><br />
  • Envoltura con Fragment: <>…</> exterior opcional

Qué es realmente JSX

JSX significa «JavaScript XML». Es una extensión sintáctica de JavaScript inventada por Jordan Walke en Facebook en 2013 como parte del anuncio original de React en la JSConf US. JSX te permite escribir marcado similar a XML directamente dentro del código JavaScript, <div className="hello">World</div>, y un transpilador (hoy casi siempre Babel) lo compila a simples llamadas de función: React.createElement('div', {className: 'hello'}, 'World'). El navegador nunca ve JSX directamente; lo que se distribuye es JavaScript normal.

La motivación original de Walke era que los lenguajes de plantillas (Mustache, Handlebars, las antiguas directivas de Angular) eran ciudadanos de segunda clase del lenguaje anfitrión: no podían usar de forma nativa los bucles, los condicionales o las variables de JavaScript, así que cada uno reinventaba los suyos. JSX invirtió la relación: en lugar de plantillas que ocasionalmente hacen JavaScript, te dio JavaScript que ocasionalmente hace marcado. El hecho de que {condition && <Item />} sea una expresión JS normal que devuelve un elemento de React es la idea que lo sostiene todo.

Desde React 17 (octubre de 2020), el runtime JSX automático significa que ya no tienes que poner import React from 'react' en cada archivo que usa JSX: Babel inserta las importaciones del runtime automáticamente. JSX también se ha adoptado mucho más allá de React: Preact, Solid, Qwik, Hono JSX, Million, Lit y el .tsx de TypeScript consumen todos la misma sintaxis. El borrador de la especificación de JSX en facebook.github.io/jsx es intencionadamente agnóstico respecto al framework.

La lista completa de diferencias HTML→JSX

  • Cambios de nombre de palabras reservadas. classclassName (porque class es una palabra reservada en JS). forhtmlFor (misma razón: for es la palabra clave de bucle). Son las dos con las que todo el mundo tropieza primero.
  • Todos los demás atributos se escriben en camelCase. tabindextabIndex, readonlyreadOnly, maxlengthmaxLength, contenteditablecontentEditable.
  • Dos excepciones importantes se mantienen en kebab-case. Los atributos aria-* (aria-label, aria-hidden) y los atributos data-* (data-testid) conservan su forma de HTML. Lo mismo para xmlns.
  • Las etiquetas de autocierre son obligatorias para los elementos vacíos: <br> se convierte en <br />, <img> se convierte en <img />, <input> se convierte en <input />. JSX es estricto como XML donde HTML es permisivo.
  • Los estilos en línea toman un objeto, no una cadena. style="color: red; background-color: blue" se convierte en style={{ color: 'red', backgroundColor: 'blue' }}. Fíjate en tres cosas: las llaves dobles (una para la expresión JSX, otra para el objeto literal), los nombres de propiedad en camelCase y los valores de cadena entre comillas. Los valores numéricos de píxeles omiten la unidad: marginTop: 16, no '16px'.
  • Los manejadores de eventos se escriben en camelCase y toman referencias de función. onclick="handleClick()" se convierte en onClick={handleClick}: fíjate en los paréntesis ausentes. onClick={handleClick()} llamaría a handleClick en el momento del renderizado y asignaría su valor de retorno como manejador, lo cual casi siempre es un error.
  • Los comentarios usan {/* … */} dentro de JSX, no <!-- … -->. La sintaxis de comentarios de HTML no tiene ningún significado dentro de JSX.
  • Los fragmentos envuelven varios hermanos. Un componente debe devolver una única raíz, así que varios elementos de nivel superior necesitan que se les envuelva en <>…</> (o el más largo <React.Fragment>…</React.Fragment>).
  • El renderizado condicional usa expresiones JS. {isVisible && <Item />} renderiza el elemento solo si la condición evalúa como verdadera; {condition ? <A /> : <B />} elige uno de dos.
  • Las llaves en el texto necesitan escaparse. La { literal dentro del contenido de texto JSX se interpreta como el inicio de una expresión. Usa {'{'} o un equivalente de entidad HTML.

SVG, accesibilidad y lo demás

El SVG funciona dentro de JSX con la misma regla de camelCase para la mayoría de los atributos: viewBox, strokeWidth, fillOpacity. Las excepciones notables: xlink:href usa la grafía especial xlinkHref (ahora obsoleta en favor del simple href), y xmlns se mantiene tal cual. Los atributos de accesibilidad siguen, por excepción, la propia convención kebab-case de ARIA: aria-label, aria-describedby y role se mantienen todos tal como están escritos.

Para el CSS, el objeto style en línea de JSX es una opción. La mayoría de las bases de código de producción usan una de tres alternativas más ricas: CSS Modules (nombres de clase con ámbito por archivo compilados por el empaquetador), Tailwind CSS (clases de utilidad que pasan limpiamente a través de className) o bibliotecas de CSS-in-JS como styled-components, Emotion o Vanilla Extract. Tailwind se ha convertido en la opción más común en los proyectos nuevos desde 2022; las clases de Tailwind no necesitan ninguna conversión al pasar de HTML a JSX, pasan como cadenas className ordinarias.

Trampas comunes de conversión

  • Los manejadores de eventos en línea que llaman a la función. onclick="alert(1)" en HTML suele convertirse en onClick={() => alert(1)} en JSX, envuelto en una función flecha para que la alerta se dispare al hacer clic, no al renderizar. Un convertidor ingenuo que produzca onClick={alert(1)} mostrará la alerta en el momento del renderizado en lugar de cuando el usuario hace clic. Este convertidor gestiona los casos comunes, pero vale la pena revisar la salida a ojo.
  • Los comentarios HTML se descartan. La mayoría de los convertidores de JSX eliminan los comentarios HTML en lugar de traducirlos a la forma {/* */}, porque esta última solo funciona en posiciones específicas dentro de JSX. Vuelve a añadir los comentarios manualmente donde los quieras.
  • Los cambios de nombre de los atributos SVG no siempre los gestionan los convertidores automáticos. stroke-width, fill-rule, clip-path y text-anchor necesitan todos formas en camelCase; comprueba la salida con cuidado si estás pegando SVG de un conjunto de iconos como Heroicons o Lucide.
  • Los atributos booleanos. <input disabled> en HTML se convierte en <input disabled /> en JSX. <input disabled="false"> en HTML está en realidad deshabilitado (cualquier valor lo activa), pero en JSX disabled={false} está correctamente desactivado: la semántica de JSX es más sensata que la de HTML.
  • Las entidades HTML. &copy; funciona en el contenido de texto JSX, pero usar el carácter Unicode literal (©) es preferible. &nbsp; funciona igual.
  • El caso de tabindex. Debería ser tabIndex. Es fácil de olvidar porque el valor suele ser 0 o -1 y parece numérico, pero el nombre del atributo aún necesita camelCase.

Cuándo recurrirías a esto

  • Migrar plantillas renderizadas en el servidor a React. Pegar un fragmento del HTML de un sitio existente y obtener JSX es el caso de uso canónico.
  • Importar iconos, insignias o exportaciones de herramientas de diseño. Heroicons, Lucide y el «Copiar como SVG» de Figma te dan todos HTML/SVG en bruto que necesita la pasada de cambio de nombre.
  • Convertir fragmentos de Tailwind UI / Flowbite / DaisyUI de sus ejemplos de HTML a JSX para un proyecto de React. Las clases de Tailwind pasan sin cambios; solo los atributos estructurales necesitan conversión.
  • Incorporar a desarrolladores que conocen HTML pero no JSX: ver las reglas mecánicas aplicadas automáticamente es más rápido que leer una lista de diferencias.
  • Prototipado rápido cuando has esbozado el marcado en HTML plano con fines de boceto y lo quieres dentro de un componente de React.

La salida funciona para cualquier consumidor de JSX, React, Preact, Solid, Qwik, Hono JSX, Million, el literal de plantilla html de Lit (con ajustes menores). No funciona para React Native, que usa componentes primitivos nativos como <View> y <Text> en lugar de elementos HTML.

Más preguntas

¿Cuál es la diferencia entre JSX y HTML?

HTML es un lenguaje de marcado que el navegador analiza directamente. JSX es una sintaxis de expresión de JavaScript que se compila a llamadas a React.createElement: nunca llega al navegador como JSX. JSX parece estricto como XML (cada etiqueta debe cerrarse, los atributos usan camelCase) porque se analiza como expresiones de JavaScript, no como HTML permisivo. La similitud visual es intencionada, pero la semántica subyacente es bastante diferente.

¿Sigo necesitando importar React en cada archivo JSX?

No desde React 17 (octubre de 2020), que introdujo el runtime JSX automático. Con él, Babel inyecta por ti las importaciones del runtime necesarias, así que los archivos que solo usan JSX no necesitan un import React from 'react' al principio del archivo. El runtime clásico sigue disponible para las cadenas de herramientas más antiguas. La mayoría de los proyectos nuevos usan el runtime automático.

¿Puedo usar JSX sin React?

Sí. JSX es una sintaxis genérica con un borrador de especificación en facebook.github.io/jsx, y muchos frameworks lo consumen: Preact, Solid, Qwik, Hono JSX, Million, Lit y la variante de plantilla etiquetada htm. Los frameworks difieren en a qué se compila JSX (Preact usa h(…), Solid se compila a primitivas reactivas de grano fino, etc.), pero la sintaxis es compartida.

¿Por qué style toma un objeto en lugar de una cadena?

Porque la sintaxis de expresión de JSX ya proporciona llaves para incrustar valores de JavaScript, y un objeto literal es la representación JS más natural de un saco de propiedades. El objeto style también admite números (la mayoría obtienen px automáticamente) y expresiones JS, cosa que una cadena no puede. La disyuntiva es la sintaxis de doble llave, ligeramente incómoda, style={{ … }}: las llaves externas para «esto es una expresión JSX», las internas para el objeto literal.

¿Se envía algo a un servidor?

No. La lógica de conversión es JavaScript puro que recorre tu cadena HTML y reescribe los atributos, todo en tu navegador. El HTML que pegas nunca sale de la página, lo cual es útil al migrar plantillas internas propietarias o marcado de componentes con endpoints de API incorporados.