HTML to JSX converter for React components

Paste HTML and get JSX that React accepts, with className and htmlFor, style objects, self-closed void tags, escaped braces, camelCased SVG attributes and comments in JSX form.

Live demo · real result from this tool

JSX

<div className="card" style={{ marginTop: "12px", backgroundColor: "#0b1220" }}>  <label htmlFor="email">Email</label>  <input id="email" type="email" defaultValue="asha@example.com" tabIndex="1" readOnly />  {/* submit */}  <button onClick={() => { save(); }} className="btn btn-primary" disabled>Save {"{"}draft{"}"}</button>  <svg viewBox="0 0 24 24"><path strokeWidth="2" fillRule="evenodd" d="M0 0h24" /></svg></div>

Inline event handlers were turned into arrow functions; check that the code still makes sense in React (this, event).

Processed on your device — nothing is uploaded.

How to use HTML to JSX

  1. Paste HTML into the HTML box. The sample is a small card with a label, an input, a button and an SVG.
  2. Tick Wrap in a React component if you want a ready-made function, and type a Component name.
  3. Copy the JSX or download it as Snippet.jsx.
  4. Read any notes under the result. They tell you when the snippet has several top-level elements or when inline handlers were converted.

What it does and when to use it

Markup from a design tool, a template or an old page is valid HTML, but React rejects much of it: class, unclosed <br> tags, CSS strings in style, curly braces in text and HTML comments. Fixing these by hand is slow and easy to get wrong in a long snippet. Use this converter when you move a static page into React, Next.js or another JSX framework, or when you paste an SVG icon into a component.

Tidy the HTML first with the HTML Cleaner if it comes from Word or a page builder, and check it with the HTML Validator if the nesting looks wrong. A converter cannot fix a missing end tag for you.

How it works

The HTML is parsed in your browser and each element is written back as JSX:

  • class → className, for → htmlFor, and other attributes get their React names.
  • style="margin-top: 12px" → style={{ marginTop: "12px" }}; vendor prefixes become WebkitUserSelect and similar.
  • Void elements such as img, input and br end in />.
  • A { or } in text becomes {"{"} or {"}"}, so JSX does not read it as code.
  • <!-- note --> becomes {/* note */}.

Worked examples

The sample card. The first line of the result is:

<div className="card" style={{ marginTop: "12px", backgroundColor: "#0b1220" }}>

The input becomes <input id="email" type="email" defaultValue="asha@example.com" tabIndex="1" readOnly />, the comment becomes {/* submit */}, and the text Save {draft} keeps its braces safely as Save {"{"}draft{"}"}.

Form state. <input type="checkbox" checked><textarea>Notes</textarea> becomes <input type="checkbox" defaultChecked /><textarea defaultValue="Notes" />, with a note that there are two top-level elements.

A component. A heading and a paragraph with onclick="go()", wrapped as PromoCard, give export default function PromoCard() { with both elements inside a fragment (<> … </>) and onClick={() => { go(); }}.

Limits and tips

  • Component names are turned into PascalCase from the words you type, so “promo card” or “promo-card” becomes PromoCard. Other characters are dropped.
  • Scripts are not rewritten as React logic. Move behaviour into event handlers or effects yourself.
  • If the HTML is really content, such as a blog post, Markdown may be easier to keep in a React project than JSX. Convert it with HTML to Markdown.

Frequently asked questions

Why does React need className instead of class?
JSX is JavaScript, and class and for are reserved words there, so React uses className and htmlFor. The converter renames them, along with about sixty other attributes whose React names are camelCased, such as tabindex to tabIndex and readonly to readOnly.
Why does value become defaultValue?
In React, value on an input makes it a controlled field that you must update with state; without an onChange handler it becomes read-only. Pasted HTML is usually a starting value, so the converter uses defaultValue and defaultChecked. Switch back to value with state when you wire the form up.
What happens to onclick and other inline handlers?
They become arrow functions, for example onClick with go() inside. A warning reminds you to check them, because code that relies on this or on the event object usually needs rewriting in React.
Does it work for SVG icons?
Yes. Hyphenated SVG attributes such as stroke-width and fill-rule become strokeWidth and fillRule, and namespaced ones such as xlink:href are converted too, so you can paste an icon straight into a component.
Can it convert a whole page?
It converts whatever you paste, but a component normally holds a fragment. Copy the body content you need rather than the doctype, head and html tags.

Written by the ToolsRift team · Last updated

Pages are drafted with AI assistance and checked by automated tests. How we write and check pages.

Was this tool useful?

Report a problem

Start typing to search every tool.

↑ ↓ to moveEnter to openEsc to close