Skip to content
GigAI Tools
svg-tools

How to Use SVG Icons in React: Components, Props and Best Practices

The practical guide to using SVG icons in React, inline vs import, turning SVGs into reusable components, passing size and colour via props, and accessibility.

Chandrabhan Shekhawat5 mins read
How to Use SVG Icons in React: Components, Props and Best Practices

React and SVG are a natural match. Because an SVG is just markup, and React is a library for describing markup, you can turn a static icon file into a live, reusable component that accepts props for size, colour and accessibility. This guide walks through the real options (from the quick copy-paste to a clean, prop-driven icon component) and the gotchas that trip people up along the way.

Why put SVG inline in React at all

You could always render an icon with <img src="/icon.svg" />, and sometimes that's the right call. But inlining the SVG directly into your JSX unlocks everything that makes SVG powerful:

  • Style it with CSS and props. An inline SVG can inherit currentColor, respond to hover, and change size without a second HTTP request.
  • No extra network request. The icon ships inside your component bundle rather than as a separate file to fetch.
  • Animate individual parts. You can target specific paths: impossible when the SVG is locked inside an <img>.

The trade-off is that inlining adds markup to your rendered DOM, so for a huge, complex illustration used once, an <img> may still be better. For the small icons that make up a UI, inline wins.

The gotcha: SVG attributes aren't JSX attributes

You can't paste raw SVG into JSX and expect it to compile. JSX uses camelCase for most attributes, so the XML you copied needs translating:

  • stroke-width becomes strokeWidth
  • fill-rule becomes fillRule
  • clip-path becomes clipPath
  • class becomes className
  • xlink:href becomes xlinkHref

Convert one icon by hand and you'll quickly see why nobody does this manually for a whole set. Paste your SVG into the SVG-to-React converter and it does the attribute translation for you, emitting a ready-to-use component, with TypeScript typings if you want them. Everything runs in the browser, so your unreleased assets never leave your machine. If your source SVGs came out of a design tool, run them through the SVG optimiser first so you're not converting bloat into a component. Our guide on optimising SVG for the web covers why that matters.

A clean, reusable icon component

The goal is a component you configure with props rather than editing the SVG each time. Here's the pattern most icon libraries follow:

function IconCheck({ size = 24, color = "currentColor", title, ...props }) {
  return (
    <svg
      width={size}
      height={size}
      viewBox="0 0 24 24"
      fill="none"
      stroke={color}
      strokeWidth={2}
      strokeLinecap="round"
      strokeLinejoin="round"
      role={title ? "img" : "presentation"}
      aria-hidden={title ? undefined : true}
      {...props}
    >
      {title ? <title>{title}</title> : null}
      <path d="M20 6 9 17l-5-5" />
    </svg>
  );
}

A few things make this good:

  • size prop sets both width and height, so <IconCheck size={32} /> just works.
  • color defaults to currentColor, meaning the icon matches surrounding text unless you override it. This is the single most useful habit for icons. It gives you dark-mode and hover support for free.
  • Spread ...props so callers can pass className, onClick or style through to the root <svg>.
  • Accessibility is handled (more on that below).

Getting colour right with currentColor

The most common frustration is an icon that won't change colour. Usually it's because the SVG has a hardcoded fill="#333" baked into its paths. When you set fill or stroke on a path directly, CSS on the parent can't override it.

The fix: strip hardcoded colours from the paths and let the icon inherit. With stroke="currentColor" (or fill="currentColor"), this works instantly:

.button:hover .icon { color: royalblue; }

No icon-specific CSS needed, the icon follows the text colour of whatever contains it.

Accessibility: don't skip this

An icon component should tell assistive technology whether it means anything.

  • Decorative icons (next to a text label that already says "Delete") should be hidden from screen readers: aria-hidden="true". Announcing them just adds noise.
  • Meaningful icons (a lone icon button with no visible text) need a label. Add a <title> element inside the SVG and reference it, or put aria-label="Delete" on the interactive element. The component above switches behaviour based on whether a title prop is passed.

Getting this right is a genuine quality signal and takes only a prop.

Managing a whole icon set

One component is easy. Forty is a system. A few approaches scale well:

  • A single sprite. Define every icon once in a hidden <svg> and reference each with <use href="#icon-name" />. This deduplicates identical icons and keeps the DOM light. We compare this approach with alternatives in SVG vs icon fonts.
  • A generated component per icon. Tools in the SVGR family, and our SVG-to-React converter, turn a folder of SVGs into a folder of typed components you import by name: import { IconCheck } from "@/icons".
  • A dynamic <Icon name="check" />. One component that looks up the right paths from a map. Convenient, but be careful it doesn't force you to bundle every icon even when a page uses two.

For most apps, generating one component per icon gives the best mix of tree-shaking, type safety and clarity.

Performance notes

Inlining icons keeps requests down, but watch two things. First, if the same icon appears dozens of times on a page, a sprite with <use> avoids repeating its path data in the DOM. Second, keep the SVGs lean. A converted component is only as small as its source, so optimise before you convert. On the flip side, don't over-engineer: for a handful of icons, plain inline components are perfectly fast.

A few habits that scale

Using SVG icons in React comes down to a few habits: inline the SVG so you can style and animate it, translate the attributes to JSX (let the SVG-to-React converter do it), drive size and colour with props, default to currentColor, and label icons for screen readers. Do that and your icons become a small, consistent, accessible system rather than a pile of one-off image tags, sharp on every screen and easy to restyle as your design evolves.

What the converter automates

The SVG to React converter does the mechanical part of everything above: camelCases the attributes, wires a typed props spread so className and aria-label pass through, and offers TypeScript, memo, forwardRef and React Native variants as toggles, with a live preview of the component it will hand you. The fiddly find-and-replace work this article describes is exactly what it exists to delete from your day. Markup you paste is processed locally.

Sources

Written by

Chandrabhan Shekhawat

Founder of Gigai Kripa Services. Builds the 250+ privacy-first browser tools on this site and writes the guides that go with them.

5 mins read

Never miss a guide

New tools and how-to articles land regularly. Follow along however you like. No inbox required.