SVG to JSX Converter
Paste SVG markup and get a ready-to-paste React component — attributes camelCased, class/for fixed.
How SVG to JSX conversion works
React (JSX) is almost HTML, but not quite: attribute names must be camelCased (stroke-width → strokeWidth), class becomes className, for becomes htmlFor, and inline style must be a JS object (style={{ opacity: 0.9 }}) rather than a string. This converter applies all of those transforms to pasted SVG and can wrap the result in a typed component that spreads {...props} onto the root <svg> — so you can pass className, width, or event handlers from the caller. data-* and aria-* attributes are left untouched, as React expects.
Everything runs in your browser. Shrink the markup first with the SVG Optimizer, convert full pages with the HTML to JSX Converter, or inline it as a data URI with SVG to Data URI.
Built and maintained by Meet Shah · Last updated
What this tool is used for
- Turning an exported icon into a React component you can drop into a codebase.
- Converting designer-supplied SVG markup into JSX without hand-editing attributes.
- Getting attribute names camel-cased correctly for a batch of icons.
- Producing a component whose fill can be driven by a prop.
- Fixing class and for attributes that JSX names differently.
Frequently Asked Questions
- What has to change for SVG to be valid JSX?
- Hyphenated and namespaced attributes become camelCase — `stroke-width` to `strokeWidth`, `xlink:href` to `xlinkHref` — `class` becomes `className`, inline `style` becomes an object, and self-closing tags need the slash JSX requires. The geometry is untouched.
- Why does the style attribute need an object?
- Because JSX passes it to React as a property, not as a string. `style="opacity: 0.9"` becomes `style={{ opacity: 0.9 }}`, with the CSS property names camelCased too. Leaving it as a string throws at runtime with a message that names the wrong thing.
- Which attributes keep their hyphens?
- `data-*` and `aria-*`, both of which React passes through unchanged. That is a genuine exception rather than an oversight — the DOM expects those names literally, so camelCasing them would break the attribute rather than fix it.
- How do I make the icon inherit its colour?
- Set `fill` or `stroke` to `currentColor`, which resolves to the surrounding text colour. That is what turns an exported icon into a themeable component — it then follows a hover state or a dark mode without any prop being passed.
- Should I inline every icon as a component?
- For a handful, yes — it keeps them stylable and avoids a request. For dozens, an SVG sprite or an icon font is smaller, because inlining duplicates the markup into every bundle that imports it and none of it compresses across files.
Common errors and gotchas
- Leaving hyphenated attributes as-is, which React ignores silently rather than erroring.
- Forgetting that `class` becomes `className` and `for` becomes `htmlFor`.
- Leaving inline style as a string, when JSX needs an object.
- Hard-coding a fill colour that should have been `currentColor` or a prop.
- Leaving duplicate ids across several inlined icons, which breaks gradient and clip-path references.