Convertidor HTML a JSX
Convierte HTML a JSX para React. Renombra class→className, for→htmlFor, parsea style strings a objetos, autocierra void elements, maneja SVG attrs.
| HTML | JSX | Nota |
|---|---|---|
class="x" | className="x" | JSX usa className porque class es palabra reservada en JavaScript |
for="x" | htmlFor="x" | JSX usa htmlFor porque for es reservado en JavaScript |
tabindex="0" | tabIndex="0" | Todos los atributos HTML van en camelCase en JSX |
id="btn-f" | onClick={f} | Los event handlers esperan una referencia de función, no una cadena de código |
style="color:red" | style={{color: 'red'}} | El style JSX espera un objeto con claves camelCase, valores como strings o números |
<br> | <br /> | Todos los elementos deben cerrarse correctamente en JSX (void elements se autocierran) |
<!-- c --> | {/* c */} | Las expresiones JavaScript en JSX viven dentro de {llaves} |
stroke-width="2" | strokeWidth="2" | Los atributos de presentación SVG usan camelCase en JSX (pero viewBox, xmlns se mantienen) |
Convertidor HTML a JSX — JSX Listo para React desde HTML Plano
Pega cualquier snippet HTML y obtén JSX que compila limpiamente en un componente React. El convertidor maneja toda diferencia común: renombra class a className y for a htmlFor, parsea strings de style en objetos JavaScript con claves camelCase, autocierra void elements, convierte atributos SVG con guion, reescribe comentarios HTML como expresiones JSX, y envuelve event handlers en arrow functions. Opcionalmente envuelve la salida en un Fragment o un function component completo, con sangría ajustable y un input para nombre del componente.
¿Por qué React no puede aceptar HTML directamente?
JSX es una extensión sintáctica de JavaScript, no HTML — y JavaScript tiene sus propias palabras reservadas que chocan con nombres de atributos HTML. Las dos grandes son:
- **class** — ya usada en JavaScript para declaraciones de clase (`class MyComponent extends React.Component`).
- **for** — usada en bucles for (`for (let i = 0; ...)`).
React renombró esos atributos a **className** y **htmlFor** para esquivar el conflicto. Cada otro renombrado camelCase (tabIndex, readOnly, autoComplete…) sigue el mismo patrón: JSX usa camelCase para propiedades DOM de varias palabras ya que las expresiones JSX se evalúan como literales de objeto JavaScript, donde los guiones no están permitidos en nombres de propiedades.
React 19 en realidad empezó a aceptar muchos atributos con ortografía HTML (`tabindex`, `readonly`) en runtime, pero el linter y la mayoría de convenciones de código todavía quieren la forma camelCase. Este convertidor produce camelCase estricto para compatibilidad con React 16 a 19.
¿Cómo se convierte el style de string a objeto?
Los strings de style HTML son pares clave-valor separados por punto y coma:
```
style="margin-top: 16px; background: #eee; font-weight: 700;"
```
JSX necesita un objeto JavaScript cuyas claves sean camelCase y cuyos valores sean strings o números:
```
style={{ marginTop: '16px', background: '#eee', fontWeight: 700 }}
```
El convertidor divide por puntos y comas, divide cada par en su primer dos puntos, convierte el nombre de propiedad a camelCase (`margin-top` → `marginTop`), y decide si poner comillas al valor. Los valores numéricos puros (`16`, `700`, `1.5`) se emiten sin comillas — React trata los valores numéricos para propiedades de tamaño como px implícitamente. Todo lo demás se pone entre comillas como string.
Algunos comportamientos sutiles:
- Las propiedades CSS personalizadas (`--my-var`) mantienen sus guiones — se ponen entre comillas como claves string: `'--my-var': 'value'`.
- `!important` se quita (el style JSX no lo soporta nativamente; usa una clase CSS real en su lugar).
- Los prefijos de vendor también van a camelCase: `-webkit-transform` → `WebkitTransform` (nota la W mayúscula, por convención de React).
Si prefieres pegar el style como string crudo y no convertirlo, desmarca 'Convertir attr style a objeto' — JSX lo acepta como string, aunque la mayoría de linters de React se quejan.
¿Cómo maneja el convertidor los event handlers como onclick?
En HTML, los atributos event handler contienen una cadena de JavaScript que el navegador hará eval cuando dispare el evento:
```
<button onclick="track('signup'); openModal()">Sign up</button>
```
Los event handlers de JSX necesitan una referencia de función (o una arrow function inline), no un string. El convertidor envuelve el código original en una arrow function para que siga ejecutándose:
```
<button onClick={() => { track('signup'); openModal() }}>Sign up</button>
```
Esto es intencionalmente una envoltura literal — preserva la lógica existente para que el snippet compile, pero generalmente querrás refactorizar a un handler con nombre:
```
<button onClick={handleSignup}>Sign up</button>
```
La opción 'Quitar event handlers' remueve los handlers inline por completo si prefieres conectarlos tú mismo en el archivo JSX. Útil al migrar markup legacy con handlers inline por todas partes.
El renombrado del atributo en sí es mecánico: `onclick` → `onClick`, `onmouseover` → `onMouseOver`, `oninput` → `onInput`, etc. El convertidor reconoce cualquier atributo `on[a-z]+` como event handler.
¿Por qué a veces veo {'{'} y < en la salida?
JSX se parsea como JavaScript, así que los caracteres `{`, `}`, `<`, y `>` tienen significado sintáctico dentro del markup:
- `{` abre una expresión JavaScript
- `<` abre una etiqueta JSX
Si esos caracteres aparecen en contenido de texto, JSX los trata como código, no texto. El convertidor los escapa para que React los renderice como caracteres literales:
- Un `{` literal se vuelve `{'{'}`
- Un `}` se vuelve `{'}'}`
- `<` se vuelve `<` (entidad HTML, que JSX preserva en contenido de texto)
- `>` se vuelve `>`
Esto importa más para bloques de visualización de código. Si pegas `<code>const x = { a: 1 };</code>`, la salida JSX leerá `<code>const x = {'{'} a: 1 {'}'};</code>` — feo pero funcionalmente correcto.
Para producción, usa un componente dedicado de resaltado de sintaxis (Prism, Shiki, Highlight.js) o envuelve el código literal en `<pre>{`código aquí`}</pre>` con un template literal — las expresiones JSX pueden contener cualquier string. El escape del convertidor es el respaldo seguro cuando no quieres refactorizar.
¿Qué hace el convertidor con los atributos SVG?
SVG tiene docenas de atributos de presentación que usan guiones: `stroke-width`, `fill-opacity`, `text-anchor`, `font-family`, y así sucesivamente. En JSX todos necesitan estar en camelCase: `strokeWidth`, `fillOpacity`, `textAnchor`, `fontFamily`.
El convertidor reconoce la lista estándar de atributos SVG con guiones (unos 35, según la API React DOM) y sólo convierte ésos — los atributos `data-*` y `aria-*` siempre mantienen sus guiones porque JSX permite guiones específicamente en esos dos espacios de nombres.
Algunos atributos SVG *ya* están en camelCase en HTML y se mantienen sin cambios: `viewBox`, `preserveAspectRatio`, `gradientUnits`, `xmlns`. La especificación HTML5 definió estos como CamelCase sensible a mayúsculas, y JSX hereda eso.
Un snippet SVG completo de una biblioteca de iconos típica — paths, transforms, gradients — se convierte limpiamente en una pegada. El log de transformaciones te muestra qué atributos se tocaron para que detectes algo inusual.
¿Debo envolver la salida en un Fragment o un componente?
Elige según a dónde va el markup:
- **Sin envoltura** — el convertidor produce JSX crudo que puedes pegar en cualquier sitio. Mejor al integrar en la sentencia return de un componente existente.
- **Fragment (`<></>`)** — envuelve múltiples elementos de nivel superior en un Fragment de React. Úsalo cuando tu HTML tiene más de una raíz (p. ej., dos divs hermanos); JSX requiere una sola raíz, y los Fragments no añaden un elemento envoltorio al DOM.
- **Function component** — envuelve todo en una definición completa `function MyComponent() { return (...); }`. Mejor para scaffolding rápido al empezar un archivo de componente nuevo desde un mockup de diseño.
El campo de nombre de componente se honra sólo en modo componente. Está restringido a caracteres alfanuméricos y debe empezar con mayúscula (convención React — los componentes deben empezar con letra mayúscula para que JSX los distinga de las etiquetas HTML).
Ninguno de los modos de envoltura inyecta `import React from 'react'` — React moderno (17+) con el JSX transform no lo necesita. Si estás en React más antiguo, añade el import manualmente.
¿Qué hay de los atributos React DOM que esperaría pero no están aquí?
El convertidor maneja el caso común. Algunos atributos tienen matices que vale la pena saber:
- **value vs defaultValue** — En HTML, `<input value="x">` establece el valor inicial. En JSX, eso crea un input *controlado* que debe tener onChange. Si quieres el comportamiento de HTML (valor inicial, luego el usuario puede editar), usa `defaultValue="x"`. El convertidor deja `value` en paz — necesitarás decidir controlado vs no controlado por caso.
- **checked vs defaultChecked** — Misma distinción controlado/no controlado para checkboxes/radios.
- **selected en `<option>`** — Usa `value` en el `<select>` padre en su lugar, ese es el idioma React.
- **dangerouslySetInnerHTML** — La única forma de React para establecer HTML directamente. El convertidor no lo genera; convierte el contenido de texto en nodos de texto JSX en su lugar.
- **ref** — Una prop específica de React que el convertidor no genera; añade manualmente al cablear focus o mediciones de DOM.
El convertidor maneja la migración *sintáctica* — hacer que tu HTML compile como JSX. La migración *semántica* (inputs controlados, refs, estado) es algo que pondrás encima según lo que el componente necesite hacer.
¿Es privado este convertidor?
Sí. La conversión sucede enteramente en tu navegador:
- La página usa el DOMParser incorporado del navegador para parsear el HTML — no se llama a ninguna API remota.
- Las reglas de transformación son código JavaScript que corre localmente.
- El botón Ejemplo llena el textarea con un string integrado; nada se descarga.
- El botón Copiar usa la API del portapapeles del navegador.
- Sin telemetría de qué HTML pegaste.
Verifica abriendo DevTools → Red y mirando el panel mientras pulsas Convertir — no se dispara ninguna petición. Esto también significa que la herramienta funciona offline una vez cargada la página, así que puedes convertir snippets de markup en un hotel, en un avión, o tras un firewall corporativo sin preocuparte por a dónde va tu código.
Características Principales
- DOMParser nativo del navegador para parsing HTML robusto (maneja markup roto/sin cerrar bien)
- Renombrado de class → className y for → htmlFor
- tabindex → tabIndex, readonly → readOnly, y 25+ otros remapeos camelCase
- Event handlers (onclick, onchange, etc.) renombrados a camelCase y envueltos en arrow functions
- Strings de style inline parseados a objetos JavaScript con claves camelCase
- Atributos SVG con guion (stroke-width, fill-opacity, text-anchor) convertidos a camelCase
- Void elements (br, img, input) auto-cerrados para modo estricto JSX
- Comentarios HTML convertidos a expresiones JSX {/* ... */}
- Atributos booleanos (disabled, checked, required) emitidos sin valor
- Atributos data-* y aria-* preservados según especificación JSX
- Tres modos de envoltura: ninguno, Fragment, o function component completo
- Sangría configurable: 2 espacios, 4 espacios, o tabs
- Input para nombre del componente en modo function-component
- Opción de quitar event handlers para migración limpia
- Log de transformaciones muestra exactamente qué cambió
- JavaScript puro — sin bibliotecas externas
- Funciona offline tras la primera carga
- 100% del lado del cliente — tu HTML se queda en tu navegador
