Why Convert HTML to JSX
In React development, we frequently need to embed existing HTML code into components. It could be HTML exported from design tools, page fragments copied from other projects, or examples taken from UI component library documentation.
Pasting HTML directly into a React component will almost certainly throw errors. The most common one is:
Skip the manual rewrite — our HTML to JSX converter handles className, camelCase props, and self-closing tags for you.
Warning: Invalid DOM property `class`. Did you mean `className`?
This happens because although JSX looks like HTML, it's essentially a syntax extension of JavaScript with its own set of rules. HTML attribute names and JSX attribute names don't always match.
Core Differences Between HTML and JSX
1. class → className
This is the most well-known difference. Since class is a reserved word in JavaScript, you must use className in JSX instead:
<!-- HTML -->
<div class="container card shadow">
<p class="text-sm text-gray-600">Hello</p>
</div>
{/* JSX */}
<div className="container card shadow">
<p className="text-sm text-gray-600">Hello</p>
</div>
2. style Attribute Changes from String to Object
In HTML, style is a string. In JSX, style must be an object with camelCase property names:
<!-- HTML -->
<div style="margin-top: 20px; background-color: #f0f0f0; font-size: 14px;">
content
</div>
{/* JSX */}
<div style={{ marginTop: '20px', backgroundColor: '#f0f0f0', fontSize: '14px' }}>
content
</div>
Notice the double curly braces {{ }} — the outer pair is JSX expression syntax, and the inner pair is the object literal.
3. for → htmlFor
The for attribute on <label> tags also needs to be renamed, for the same reason as class:
<!-- HTML -->
<label for="email">Email</label>
<input id="email" type="email">
{/* JSX */}
<label htmlFor="email">Email</label>
<input id="email" type="email" />
4. Self-Closing Tags
In HTML, many tags don't require a closing tag (like <br>, <img>, <input>), but JSX requires all tags to be closed. Tags without children must use self-closing syntax:
<!-- HTML -->
<img src="logo.png" alt="logo">
<br>
<input type="text" placeholder="Enter name">
<meta charset="utf-8">
{/* JSX */}
<img src="logo.png" alt="logo" />
<br />
<input type="text" placeholder="Enter name" />
<meta charSet="utf-8" />
As a side note, charset also becomes charSet.
5. Event Handlers
In HTML, event attributes are all lowercase with string values containing code:
<button onclick="handleClick()">Click me</button>
In JSX, event names use camelCase and values are function references:
<button onClick={handleClick}>Click me</button>
Common mappings:
| HTML Attribute | JSX Attribute |
|----------------|---------------|
| onclick | onClick |
| onchange | onChange |
| onsubmit | onSubmit |
| onkeydown | onKeyDown |
| onmouseover | onMouseOver |
| onfocus | onFocus |
| onblur | onBlur |
6. Other Attribute Name Differences
There are several other attributes with different names in JSX:
| HTML Attribute | JSX Attribute | Notes |
|----------------|---------------|-------|
| tabindex | tabIndex | camelCase |
| readonly | readOnly | camelCase |
| maxlength | maxLength | camelCase |
| cellspacing | cellSpacing | camelCase |
| cellpadding | cellPadding | camelCase |
| colspan | colSpan | camelCase |
| rowspan | rowSpan | camelCase |
| usemap | useMap | camelCase |
| contenteditable | contentEditable | camelCase |
| crossorigin | crossOrigin | camelCase |
| datetime | dateTime | camelCase (time tag) |
| autocomplete | autoComplete | camelCase |
| autofocus | autoFocus | camelCase |
| autoplay | autoPlay | camelCase |
Essentially, all multi-word HTML attributes need to be converted to camelCase in JSX.
Common Conversion Pitfalls
Different Comment Syntax
<!-- HTML comment -->
{/* JSX comment */}
this in Inline Event Handlers
In HTML, onclick="foo()" calls a global function. In JSX, you need to be careful about this binding — usually handled with arrow functions or bind.
Boolean Attributes
In HTML, certain attributes take effect just by being present (like disabled, checked, readonly). In JSX, you need to explicitly pass boolean values:
<!-- HTML -->
<input disabled>
<input checked>
{/* JSX */}
<input disabled={true} />
<input checked={true} />
{/* or more concisely */}
<input disabled />
<input checked />
dangerouslySetInnerHTML
If you really need to set HTML content directly (for example, rendering rich text), you can't just use innerHTML. You must use dangerouslySetInnerHTML:
<div dangerouslySetInnerHTML={{ __html: '<p>Raw HTML content</p>' }} />
React intentionally made this API look "ugly" to remind you: directly injecting HTML carries XSS risk, use it with caution.
Tool Recommendations
Manual HTML-to-JSX conversion is tedious and error-prone. For complex HTML fragments, automated tools are recommended:
- HTML to JSX online converter: paste HTML and get back properly formatted JSX with one click
- VS Code extensions: some extensions can handle conversion right in the editor
- AI tools like ChatGPT / Claude: for particularly complex structures, AI can handle things more intelligently
A good converter should automatically handle:
class→classNamestylestring → objectfor→htmlFor- self-closing tag completion
- camelCase attribute names
- event name conversion
Summary
HTML to JSX conversion seems simple but has many details. Remember a few core principles to avoid most pitfalls:
- Use camelCase for attributes —
className,htmlFor,onClick, etc. - style is an object — not a string
- All tags must close — use self-closing when there are no children
- JS expressions use
{}— instead of string interpolation in HTML
Master these rules, combine them with the right tools, and HTML-to-JSX conversion will no longer be a hassle.
relatedTools
Related Articles
Regex Not Matching? Troubleshoot These 6 Common Pitfalls
How to troubleshoot when a regex doesn't match or matching fails? This article walks through 6 common pitfalls — greedy quantifiers, missing flags, unescaped special chars, lookaround assertions, newline handling, and Unicode properties — with before/after examples to help you quickly locate regex debugging issues.
Online Regex Explainer: Visualize and Understand Regular Expressions
Learn how to parse and understand regular expressions. Understand regex syntax structure, matching principles, and how to use visualization tools to analyze complex patterns.
Online CSS Gradient Generator: Create Beautiful Background Gradients
Learn how to use an online tool to create CSS linear and radial gradients. Understand gradient syntax, color matching techniques, and how to apply gradient effects in web design.