Guide
Turning raw SVG into React, Vue and Astro components
Designers export icons as SVG files, and developers want them as components that accept a size, a colour and a class name. Pasting an SVG straight into JSX does not work, because React uses a different attribute vocabulary from HTML and SVG, and a style string is not allowed at all. Doing the conversion by hand for each icon is dull and error-prone. This page converts one SVG at a time to a component for React, Vue 3 or Astro and shows exactly what changed.
What React needs
In JSX, attributes are JavaScript property names. stroke-width becomes strokeWidth, stop-color becomes stopColor, class becomes className and xlink:href becomes xlinkHref. A style attribute written as style="color: #111827; stroke-linejoin: round" must be an object, style={{ color: '#111827', strokeLinejoin: 'round' }}. Self-closing tags need the closing slash. The converter handles all of these, and tells you in a note which attribute names it renamed.
A worked example
Press Sample to load a 24 by 24 bell icon with an XML declaration, a comment, a title, a gradient and a circle filled with it, named BellIcon. The React TypeScript output starts import type { SVGProps } from 'react'; and then export function BellIcon(props: SVGProps<SVGSVGElement>) {. The root is <svg width="24" height="24" viewBox="0 0 24 24" fill="none" className="icon icon-bell" style={{ color: '#111827', strokeLinejoin: 'round' }} {...props}>. The path now has strokeWidth="2" and strokeLinecap="round", the gradient stops have stopColor, and the circle keeps fill="url(#dot)". The note reads that the class attribute was renamed to className.
Props, size and colour
The {...props} at the end of the root element passes whatever you give the component onto the SVG, so <BellIcon width={32} className="text-red-500" /> works. Because props come last, they override the sizes in the file. Tick Remove width and height to drop the fixed 24 by 24 entirely; the icon then scales with its container through the viewBox, and you set the size in CSS. Tick “Use currentColor” and every hard-coded fill and stroke colour becomes currentColor, so in the sample the two stroke="#111827" lines turn into stroke="currentColor" and the icon follows the CSS text colour. Gradient fills such as url(#dot) are not changed, and neither is the color in the style attribute.
Vue and Astro
Vue 3 output is a single-file component: a script setup block with defineOptions({ name: 'BellIcon', inheritAttrs: false }) and a template whose svg uses v-bind="$attrs". Attribute names stay as in the original, since Vue accepts SVG names, and class and style remain strings. Astro output has a frontmatter block typing Astro.props and spreads them onto the svg, so you pass attributes the same way. Neither of the two needs a conversion of attribute names.
Edge cases
Ids inside the SVG, such as the gradient dot, are global in the page. If you render two copies of an icon on one page the ids repeat; this is harmless when both gradients are identical but a hazard if they differ. The title element supplies an accessible name; keep it for meaningful icons, and remove it, together with aria-hidden, for decorative ones.
Limits
The converter works on one SVG. It does not optimise paths, so run the SVG Optimizer first for the smallest components. It does not remove script elements or inline event handlers, so only convert SVG you trust. Text elements keep their fonts. Everything is processed in your browser.
Related tools
- SVG Optimizer shrinks the source before conversion.
- SVG Sprite Generator is the lighter option for many icons.
- SVG to CSS Converter embeds an icon as a background or mask.
- Image to Base64 encodes other file types for inline use.
Checked against the current version of the SVG to React, Vue & Astro Component on .

