Conversor HTML para JSX
Converte HTML em JSX para React. Renomeia class→className, for→htmlFor, parseia style strings em objetos, autofecha void elements, lida com SVG attrs.
| HTML | JSX | Nota |
|---|---|---|
class="x" | className="x" | JSX usa className porque class é palavra reservada em JavaScript |
for="x" | htmlFor="x" | JSX usa htmlFor porque for é reservado em JavaScript |
tabindex="0" | tabIndex="0" | Todos os atributos HTML em camelCase no JSX |
id="btn-f" | onClick={f} | Event handlers esperam uma referência de função, não uma string de código |
style="color:red" | style={{color: 'red'}} | O style JSX espera um objeto com chaves camelCase, valores como strings ou números |
<br> | <br /> | Todos os elementos devem ser fechados corretamente no JSX (void elements se autofecham) |
<!-- c --> | {/* c */} | Expressões JavaScript em JSX vivem dentro de {chaves} |
stroke-width="2" | strokeWidth="2" | Atributos de apresentação SVG usam camelCase no JSX (mas viewBox, xmlns permanecem) |
Conversor HTML para JSX — JSX Pronto para React a partir de HTML Simples
Cole qualquer snippet HTML e obtenha JSX que compila limpo em um componente React. O conversor lida com toda diferença comum: renomeia class para className e for para htmlFor, parseia strings de style em objetos JavaScript com chaves camelCase, autofecha void elements, converte atributos SVG com hífen, reescreve comentários HTML como expressões JSX, e envolve event handlers em arrow functions. Opcionalmente envolve a saída em um Fragment ou um function component completo, com recuo ajustável e um campo para nome do componente.
Por que React não pode simplesmente aceitar HTML diretamente?
JSX é uma extensão sintática de JavaScript, não HTML — e JavaScript tem suas próprias palavras reservadas que conflitam com nomes de atributos HTML. As duas grandes são:
- **class** — já usada em JavaScript para declarações de classe (`class MyComponent extends React.Component`).
- **for** — usada em loops for (`for (let i = 0; ...)`).
React renomeou esses atributos para **className** e **htmlFor** para evitar o conflito. Todo outro renomeio camelCase (tabIndex, readOnly, autoComplete…) segue o mesmo padrão: JSX usa camelCase para propriedades DOM de múltiplas palavras porque expressões JSX são avaliadas como literais de objeto JavaScript, onde hífens não são permitidos em nomes de propriedades.
React 19 na verdade começou a aceitar muitos atributos com ortografia HTML (`tabindex`, `readonly`) em runtime, mas o linter e a maioria das convenções de código ainda querem a forma camelCase. Este conversor produz camelCase estrito para compatibilidade com React 16 a 19.
Como style é convertido de string para objeto?
Strings de style HTML são pares chave-valor separados por ponto e vírgula:
```
style="margin-top: 16px; background: #eee; font-weight: 700;"
```
JSX precisa de um objeto JavaScript cujas chaves sejam camelCase e cujos valores sejam strings ou números:
```
style={{ marginTop: '16px', background: '#eee', fontWeight: 700 }}
```
O conversor divide por ponto e vírgula, divide cada par no primeiro dois-pontos, converte o nome da propriedade para camelCase (`margin-top` → `marginTop`), e decide se coloca aspas no valor. Valores puramente numéricos (`16`, `700`, `1.5`) são emitidos sem aspas — React trata valores numéricos para propriedades de tamanho como px implicitamente. Tudo o mais é colocado entre aspas como string.
Alguns comportamentos sutis:
- Propriedades CSS personalizadas (`--my-var`) mantêm seus hífens — são colocadas entre aspas como chaves string: `'--my-var': 'value'`.
- `!important` é retirado (style JSX não suporta nativamente; use uma classe CSS real em vez).
- Prefixos de vendor também ficam camelCase: `-webkit-transform` → `WebkitTransform` (note o W maiúsculo, por convenção React).
Se preferir colar o style como string crua e não converter, desmarque 'Converter attr style em objeto' — JSX aceita como string, embora a maioria dos linters React reclame.
Como o conversor lida com event handlers como onclick?
Em HTML, atributos event handler contêm uma string de JavaScript que o navegador irá eval quando o evento disparar:
```
<button onclick="track('signup'); openModal()">Sign up</button>
```
Event handlers JSX precisam de uma referência de função (ou uma arrow function inline), não uma string. O conversor envolve o código original em uma arrow function para que ainda execute:
```
<button onClick={() => { track('signup'); openModal() }}>Sign up</button>
```
Esta é intencionalmente uma envoltura literal — preserva a lógica existente para que o snippet compile, mas você geralmente vai querer refatorar em um handler nomeado:
```
<button onClick={handleSignup}>Sign up</button>
```
A opção 'Remover event handlers' remove handlers inline inteiramente se você preferir anexá-los você mesmo no arquivo JSX. Útil ao migrar markup legacy com handlers inline por toda parte.
O renomeio do atributo em si é mecânico: `onclick` → `onClick`, `onmouseover` → `onMouseOver`, `oninput` → `onInput`, etc. O conversor reconhece qualquer atributo `on[a-z]+` como event handler.
Por que às vezes vejo {'{'} e < na saída?
JSX é parseado como JavaScript, então os caracteres `{`, `}`, `<`, e `>` têm significado sintático dentro do markup:
- `{` abre uma expressão JavaScript
- `<` abre uma tag JSX
Se esses caracteres aparecem em conteúdo de texto, JSX os trata como código, não texto. O conversor os escapa para que React os renderize como caracteres literais:
- Um `{` literal vira `{'{'}`
- Um `}` vira `{'}'}`
- `<` vira `<` (entidade HTML, que JSX preserva em conteúdo texto)
- `>` vira `>`
Isso importa mais para blocos de exibição de código. Se você cola `<code>const x = { a: 1 };</code>`, a saída JSX lerá `<code>const x = {'{'} a: 1 {'}'};</code>` — feio mas funcionalmente correto.
Para produção, use um componente dedicado de destaque de sintaxe (Prism, Shiki, Highlight.js) ou envolva o código literal em `<pre>{`código aqui`}</pre>` com um template literal — expressões JSX podem conter qualquer string. O escape do conversor é o fallback seguro quando você não quer refatorar.
O que o conversor faz com atributos SVG?
SVG tem dezenas de atributos de apresentação que usam hífens: `stroke-width`, `fill-opacity`, `text-anchor`, `font-family`, e assim por diante. Em JSX todos precisam estar em camelCase: `strokeWidth`, `fillOpacity`, `textAnchor`, `fontFamily`.
O conversor reconhece a lista padrão de atributos SVG com hífen (cerca de 35, conforme a API React DOM) e só converte esses — atributos `data-*` e `aria-*` sempre mantêm seus hífens porque JSX permite hífens especificamente nesses dois namespaces.
Alguns atributos SVG *já* são camelCase em HTML e permanecem inalterados: `viewBox`, `preserveAspectRatio`, `gradientUnits`, `xmlns`. A especificação HTML5 definiu esses como sensíveis a maiúsculas CamelCase, e JSX herda isso.
Um snippet SVG completo de uma biblioteca de ícones típica — paths, transforms, gradients — converte limpo em uma colada. O log de transformações mostra quais atributos foram tocados para você identificar qualquer coisa incomum.

Devo envolver a saída em um Fragment ou um componente?
Escolha baseado em onde o markup vai:
- **Sem envoltório** — o conversor produz JSX cru que você pode colar em qualquer lugar. Melhor ao integrar na sentença return de um componente existente.
- **Fragment (`<></>`)** — envolve múltiplos elementos de nível superior em um React Fragment. Use quando seu HTML tem mais de uma raiz (por exemplo, dois divs irmãos); JSX requer uma única raiz, e Fragments não adicionam um elemento envoltório ao DOM.
- **Function component** — envolve tudo em uma definição `function MyComponent() { return (...); }` completa. Melhor para scaffolding rápido ao começar um novo arquivo de componente a partir de um mockup de design.
O campo nome do componente é honrado apenas no modo componente. É restrito a caracteres alfanuméricos e deve começar com maiúscula (convenção React — componentes devem começar com letra maiúscula para JSX distingui-los de tags HTML).
Nenhum dos modos de envoltório injeta `import React from 'react'` — React moderno (17+) com o JSX transform não precisa. Se você está em React mais antigo, adicione o import manualmente.
Ele pode produzir um componente TypeScript (.tsx) tipado?
Sim. Marque **TypeScript (.tsx)** e mude o modo de envoltório para **Function component** — o conversor emite um function component React tipado com tipo de retorno `React.JSX.Element`:
```
function MyComponent(): React.JSX.Element {
return (
...
);
}
```
Esse é o passo mais repetitivo ao migrar um mockup de design para uma base de código TypeScript/Next.js: você cola o JSX convertido e depois digita à mão a assinatura e a anotação de retorno. Isso faz por você para que a saída esteja pronta para colar em um arquivo `.tsx`.
A caixa **Adicionar import React** é independente e funciona em todos os modos de envoltório. React moderno (17+) com o JSX transform automático **não** precisa de `import React from 'react'`, então está desativada por padrão — sua saída fica limpa. Marque apenas se você mira React mais antigo (16 ou uma configuração sem o novo transform), onde o import é obrigatório. Quando marcada, `import React from 'react';` é anteposto ao que você gerar (JSX cru, Fragment ou componente).
O tipo de retorno `React.JSX.Element` funciona com as definições de tipos do React 18+; em `@types/react` mais antigos você pode trocar por `JSX.Element` após colar.
Por que meu style JSX não aplica — para onde foi !important?
Os objetos de style inline do JSX **não** suportam `!important`. O conversor o retira de cada declaração, então `style="color: red !important"` vira `style={{ color: 'red' }}`. O serializador de estilos inline do React (e o `element.style.setProperty` subjacente que ele usa) ignora silenciosamente `!important` na forma de objeto, por isso um valor que funcionava em HTML cru pode parecer não fazer nada após a conversão.
Se você realmente precisa da prioridade de override, mova essa declaração para uma classe CSS real (ou CSS Module / styled-component) e aplique via `className` — essa é a correção idiomática do React e a única forma confiável de obter o comportamento de `!important`. Estilos inline são para valores dinâmicos e calculados, não para vencer batalhas de especificidade.
Se um estilo falta por completo (não só perde prioridade), verifique se você não colou um shorthand que React não consegue camelCasear limpo, e se o valor está entre aspas como string onde não é um número sem unidade.
E sobre atributos React DOM que eu esperaria mas não estão aqui?
O conversor lida com o caso comum. Alguns atributos têm nuances que vale a pena saber:
- **value vs defaultValue** — Em HTML, `<input value="x">` define valor inicial. Em JSX, isso cria um input *controlado* que deve ter onChange. Se você quer o comportamento HTML (valor inicial, depois usuário pode editar), use `defaultValue="x"`. O conversor deixa `value` em paz — você precisa decidir controlado vs não-controlado por caso.
- **checked vs defaultChecked** — Mesma distinção controlado/não-controlado para checkboxes/radios.
- **selected em `<option>`** — Use `value` no `<select>` pai em vez, é o idioma React.
- **dangerouslySetInnerHTML** — A única forma de React para definir HTML diretamente. O conversor não gera isso; converte conteúdo de texto em nós de texto JSX em vez.
- **ref** — Uma prop específica de React que o conversor não gera; adicione manualmente ao ligar focus ou medições DOM.
O conversor lida com a migração *sintática* — fazer seu HTML compilar como JSX. A migração *semântica* (inputs controlados, refs, state) é algo que você vai colocar por cima dependendo do que o componente precisa fazer.
Este conversor é privado?
Sim. A conversão acontece inteiramente no seu navegador:
- A página usa o DOMParser embutido do navegador para parsear o HTML — nenhuma API remota é chamada.
- As regras de transformação são código JavaScript que roda localmente.
- O botão Exemplo preenche o textarea com uma string embutida; nada é baixado.
- O botão Copiar usa a API de área de transferência do navegador.
- Sem telemetria de qual HTML você colou.
Verifique abrindo DevTools → Rede e observando o painel enquanto clica Converter — nenhuma requisição dispara. Isso também significa que a ferramenta funciona offline depois que a página carrega, então você pode converter snippets de markup em um hotel, num avião, ou atrás de um firewall corporativo sem se preocupar para onde seu código vai.
Recursos Principais
- DOMParser nativo do navegador para parsing HTML robusto (lida com markup quebrado/não fechado bem)
- Renomeio class → className e for → htmlFor
- tabindex → tabIndex, readonly → readOnly, e 25+ outros remapeamentos camelCase
- Event handlers (onclick, onchange, etc.) renomeados para camelCase e envolvidos em arrow functions
- Strings de style inline parseadas em objetos JavaScript com chaves camelCase
- Atributos SVG com hífen (stroke-width, fill-opacity, text-anchor) convertidos para camelCase
- Void elements (br, img, input) auto-fechados para modo estrito JSX
- Comentários HTML convertidos para expressões JSX {/* ... */}
- Atributos booleanos (disabled, checked, required) emitidos sem valor
- Atributos data-* e aria-* preservados conforme spec JSX
- Saída de componente TypeScript (.tsx) com import React opcional
- Três modos de envoltório: nenhum, Fragment, ou function component completo
- Recuo configurável: 2 espaços, 4 espaços, ou tabs
- Campo nome do componente para modo function-component
- Opção de remover event handlers para migração limpa
- Log de transformações mostra exatamente o que mudou
- JavaScript puro — sem bibliotecas externas
- Funciona offline após o primeiro carregamento
- 100% no cliente — seu HTML fica no seu navegador
