React SVG Icons

By the Axialis Engineering team ·

React SVG Icons

Importing raw .svg files into a React app usually means wiring up SVGR or vite-plugin-svgr, then losing your editor's exact paths to a build step. IconVectors skips that: it exports each icon as a typed React component you paste straight into your project, with React.SVGProps<SVGSVGElement> props, a forwardRef for refs, an optional accessible label, and currentColor for CSS theming.

This guide covers the export steps in IconVectors, a production-ready component template, and the React-specific patterns for accessibility, theming, and tree-shaking. If you'd rather keep .svg files and let your bundler generate components, the companion vite-plugin-svgr tutorial shows that route instead.

Three ways to ship SVG icons in React

There is no single right answer. Pick the approach that matches how many icons you ship and how you theme them. This table summarizes the trade-offs; the rest of this guide covers the typed-component route in depth, and the links point to the setup guide for each.

Approach Developer experience Bundle size Theming Accessibility
Inline SVG in JSX No build step; paste markup straight into a component. Fine for a few marks; repeated markup bloats components. currentColor and CSS work directly. Full control of role and aria-* per element.
SVGR / typed components Import a .svg as a component with props and TypeScript types. Tree-shakes per icon; each used icon inlines once. currentColor plus className pass-through. Forward title and aria-label as props.
SVG sprite (<use>) One sprite file; reference symbols by id. Best when icons repeat; geometry stored once and cached. currentColor inherits; deep CSS is limited across <use>. Set role and aria-label on the wrapping <svg>.

In practice: reach for SVGR / vite-plugin-svgr when you want typed components and per-icon tree-shaking; build an SVG sprite when the same icons repeat across many screens; and keep icons inline for one-off marks. Whichever you choose, make them themeable with currentColor and CSS and accessible with the right ARIA roles and labels.

When to choose React TypeScript

Draw, Import or Trace your icon

IconVectors editor showing a heart icon on the 24-pixel grid with the Source Code panel open, ready to copy as a React component

Export a React TypeScript component from IconVectors

  1. Design on a consistent grid (e.g., 24×24). Keep strokes aligned to whole pixels.
  2. Set theming strategy: for single-color icons, prefer currentColor on fill or stroke so CSS can control color.
  3. Open the code viewer (F3) and switch to the React (TS) tab.
  4. Copy the generated component (or use Export) and save it to your project, e.g., icons/HeartIcon.tsx.

Component template (typed & forwardRef)

import * as React from "react";

export type IconProps = React.SVGProps<SVGSVGElement> & {
  /** Optional accessible label; if omitted, icon is decorative */
  title?: string;
  /** Optional size in px (applies to width/height) */
  size?: number | string;
};

export const HeartIcon = React.forwardRef<SVGSVGElement, IconProps>(
  function HeartIcon({ title, size = 24, ...props }, ref) {
    const aria = title
      ? { role: "img", "aria-label": title }
      : { "aria-hidden": "true" as const };

    return (
      <svg
        ref={ref}
        viewBox="0 0 24 24"
        width={size}
        height={size}
        {...aria}
        {...props}
      >
        <path
          fill="none"
          stroke="currentColor"
          strokeWidth="1"
          strokeLinecap="round"
          strokeLinejoin="round"
          d="M2.5 9C2.5 2.5 10 3 12 7.5C14 3 21.5 2.5 21.5 9C21.5 15.4 12 21.5 12 21.5C12 21.5 2.5 15.6 2.5 9z"
        />
      </svg>
    );
  }
);

Usage examples

import { HeartIcon } from "./icons/HeartIcon";

// 1) Decorative icon (screen readers ignore)
<HeartIcon className="h-5 w-5 text-rose-600" aria-hidden="true" />

// 2) Informative icon with label
<HeartIcon className="h-5 w-5" title="Favorite" />

// 3) Set size via prop or CSS
<HeartIcon size={20} style={{ color: "#16a34a" }} />

Using an SVG sprite in React (alternative)

If you maintain a global sprite, reference symbols with <use href="…"/> (modern React supports href):

// sprite definition lives once in your app (e.g., in _app.tsx or index.html)
/*
<svg style="display:none">
  <symbol id="icon-heart-24" viewBox="0 0 24 24">
    <path fill="none" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"
          d="M2.5 9C2.5 2.5 10 3 12 7.5C14 3 21.5 2.5 21.5 9C21.5 15.4 12 21.5 12 21.5C12 21.5 2.5 15.6 2.5 9z"/>
  </symbol>
</svg>
*/

export function HeartIconSprite(props: React.SVGProps<SVGSVGElement>) {
  return (
    <svg width={24} height={24} aria-hidden="true" {...props}>
      <use href="#icon-heart-24" fill="currentColor" />
    </svg>
  );
}

Accessibility checklist

Theming with currentColor

Keep fills or strokes on the main shape set to currentColor so icons inherit text color from CSS (utility classes or variables). For fixed accents, use hard-coded colors on secondary paths.

.btn-icon { color: #2563eb; }
[data-theme="dark"] .btn-icon { color: #93c5fd; }
<button className="btn-icon inline-flex items-center gap-2">
  <HeartIcon size={20} aria-hidden="true" /> Save
</button>

Performance & packaging tips

Related guides

Start Making SVG Icons Today with IconVectors

Download the fully-functional 30‑Day Free Trial and unlock your icon design workflow.

Version 1.70 for Windows, macOS, and Linux