TL;DR
- SVG attributes like
stroke-widthbecomestrokeWidthin JSX. -
class→className. - Numeric values become
{expressions}. - Inline styles become objects.
-
xmlnsand XML comments are removed. - The converter outputs either JSX or TSX with
SVGProps. - Use automation (SVGR or SVGCode) for large icon sets.
- Import only what you need to keep bundle sizes small.
Converting an SVG file into a React component is more than just pasting markup into a .jsx or .tsx file. React uses JSX, which is stricter than HTML/XML and requires specific changes to ensure your SVG renders correctly and remains maintainable. In this post, we’ll explore every transformation that takes place—from attribute casing to TypeScript typing—so you understand exactly what our free SVG to React converter does under the hood.
What Actually Changes?
Kebab‑case Attributes Become camelCase
SVG uses attributes like stroke-width, fill-rule, and clip-path. JSX requires property names that are valid JavaScript identifiers, so these become:
| SVG Attribute | React JSX |
|---|---|
stroke-width |
strokeWidth |
stroke-linecap |
strokeLinecap |
stroke-linejoin |
strokeLinejoin |
fill-rule |
fillRule |
clip-path |
clipPath |
font-size |
fontSize |
stroke-dasharray |
strokeDasharray |
class Becomes className
In SVG you write class="icon", but in JSX you must use className="icon" because class is a reserved word in JavaScript.
Numeric Attributes Are Converted to Expressions
React treats string values differently from numbers. For numeric SVG attributes like width, height, x, y, cx, r, etc., the converter outputs {value} instead of "value".
<circle cx="12" cy="12" r="10" />
becomes:
<circle cx={12} cy={12} r={10} />
Inline Styles Become Objects
If your SVG uses style="fill: red; stroke: blue;", it must be converted to a JavaScript object:
style={{ fill: 'red', stroke: 'blue' }}
xmlns and Namespace Declarations Are Removed
React automatically uses the correct SVG namespace, so xmlns and other XML namespace declarations are unnecessary and removed.
Comments and XML Declarations Are Stripped
Any <?xml version="1.0"?> or HTML comments are removed because they’re invalid in JSX.
JSX vs TSX Output
The converter can output either JavaScript (JSX) or TypeScript (TSX). Both share the same transformations, but TSX adds type definitions.
JavaScript (JSX)
const SVGComponent = ({ title, ...props }) => (
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
{...props}>
{title ? <title>{title}</title> : null}
<path d="M12 2L2 7l10 5 10-5-10-5z" fill="currentColor" />
</svg>
);
export default SVGComponent;
TypeScript (TSX)
import type { SVGProps } from "react";
interface SVGComponentProps extends SVGProps<SVGSVGElement> {
title?: string;
}
const SVGComponent = ({ title, ...props }: SVGComponentProps) => (
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
{...props}>
{title ? <title>{title}</title> : null}
<path d="M12 2L2 7l10 5 10-5-10-5z" fill="currentColor" />
</svg>
);
export default SVGComponent;
Key TSX advantages:
-
SVGPropsgives autocomplete and type checking. - Pass
className,onClick,style, or any SVG prop safely. -
titleprop is explicitly typed.
How Props Work After Conversion
The converter spreads {...props} onto the root <svg>. This means you can override attributes:
<SVGComponent width={48} height={48} className="my-icon" fill="red" />
From One Icon to a Whole Library: Tools & Workflows
Now that you understand manual transformations, let’s scale it.
Manual vs. Automated
| Method | Best For | Pros | Cons |
|---|---|---|---|
| Manual | One‑off icons | Full control | Tedious |
| SVGR | Large sets | Fast, tree‑shakable | Requires setup |
| SVGCode | Quick conversions | Instant, no setup | Not for batch |
SVGR is popular for local automation:
npx @svgr/cli checkmark.svg --out-dir src/icons
Tree‑Shaking & Bundle Size
Import only what you use:
import { CheckmarkIcon } from './icons'; // ✅
Avoid importing entire packs:
import * as Icons from '@heroicons/react/24/outline'; // ❌
Dynamic Imports & Code Splitting
For large icon libraries, use React.lazy:
const CheckmarkIcon = React.lazy(() => import('./icons/CheckmarkIcon'));
Common Pitfalls
-
currentColorinherits parent text color. - Test after conversion for complex filters/gradients.
- Ensure your SVG has a
viewBox.
Try It Yourself
- Paste your SVG into SVGCode.
- Click the React tab.
- Toggle JSX/TSX.
- Copy or download.
Thanks for reading! If you found this useful, check out our other converters:
Top comments (0)