Turn an SVG into a React component
JSX is not HTML, so an icon dropped into a component file will not compile until its attribute names are respelled. Paste the markup above and a finished component comes back: hyphenated attributes camelCased, class renamed to className, style turned into an object rather than a string, the prolog and the drawing program's leftovers gone, and props spread onto the root so you can size or colour the thing at the point you use it.
Turn an SVG into a React component
Paste an SVG and get a React component back, with the attributes spelled the way React wants them and props spread onto the root so you can use it more than once. The file is read and rewritten by this tab, on your own machine, so the markup you paste is not uploaded anywhere.
SVG to JSX, step by step
- Choose the file or paste the markupChoosing a file also names the component after it, so my-logo.svg comes back as MyLogo. Pasting gets you a component called Icon, which you can rename in a second.
- Say whether you want typesThe TypeScript switch types the props as SVGProps of SVGSVGElement, which is the type React itself uses for an svg element and the one your editor will expect.
- Copy it into your projectThe output is a whole module, imports and export included, so it goes straight into a new file rather than needing anything wrapped around it first.
The attribute names are the job, and there are three kinds of them
Most attributes are mechanical: React wants stroke-width as strokeWidth and fill-rule as fillRule, and a hyphen followed by a letter becomes that letter in capitals. A second group cannot be worked out that way and has to be known, which is why class becomes className, xlink:href becomes xlinkHref and xml:space becomes xmlSpace. The third group is the trap. Every data- and aria- attribute stays exactly as it is, hyphens and all, because React passes those straight through to the DOM and quietly drops anything camelCased instead, so a rule that respells everything loses your test hooks and your accessibility attributes without a word of complaint. On top of that, style has to become an object with camelCased keys rather than the string it is in the file, and a brace inside a text element has to be escaped or JSX reads it as an expression.
The reason this is a job at all is that JSX looks so nearly like HTML that people expect to paste
and go. Then the build fails on stroke-width, or worse, it compiles and something is silently
missing, because React did not recognise an attribute and threw it away without saying so.
The other half of the work is everything an export leaves behind. Illustrator writes an XML prolog,
a generator comment and a couple of namespaces it needs and you do not. Inkscape writes a
sodipodi:namedview element recording where the window was when you saved. None of it renders, all
of it makes the component harder to read, and a lot of it will not compile as JSX at all because
the names have colons in them.
What is deliberately left alone is the drawing. Paths are not rounded, groups are not flattened and nothing is merged, because that is a different job with different risks and it has its own page. Run this one to get a component, and run that one if the component turns out to be larger than you wanted.
Questions
How is this different from running SVGR?
It is the same job for one file with nothing to install. SVGR is the right answer when a build step should be doing this every time your designers export a new icon set. This is the right answer when somebody has sent you one file and you want the component now, on a machine where you would rather not add a dependency to find out whether the icon is even the right one.
Why does the component take props at all?
Because a component you cannot size, colour or label is one you will paste a second copy of the next time you need it slightly different. The spread sits after everything read out of the file, so anything passed in wins. Give it a className, a width, an aria-label or an onClick and they all reach the root element.
What happens to the ids inside the file?
They are kept exactly as they were, which matters because clip paths, gradients and masks refer to them. It also means two copies of the same icon on one page carry the same ids, which is invalid and occasionally visible when a gradient renders from the wrong definition. Rename them in the file, or render the icon once and reuse it.
Can it give me a Vue or Svelte component instead?
Not today. The attribute rules are genuinely different for each framework, and a converter that half knows a second one is worse than a page that says it only does React. If it turns out people want the others, they get pages of their own rather than a dropdown on this one.
Is my markup uploaded anywhere?
No. Your markup is handed to the browser's own XML parser inside this tab, walked element by element, and written back out as JSX. None of that wants a server, which is why there is no queue, no account and no limit on how many you do. One event is sent saying a conversion happened here, and nothing rides along with it, so the file name, the size and every byte of the drawing stay on your machine.
Other things here
There is a full list on the free tools page. They all work the same way: in the browser, with nothing to install.
The tool is free. So is the thought.
This page did one small job. Edmund is for the thing you thought of while doing it: a capture app for iPhone, iPad and Mac that files a note the moment you have it, so it does not get lost between having it and writing it down.
See what Edmund does