dilkhush-raj
Articles

How to convert SVG to React components

A comprehensive guide to converting SVG assets into flexible and maintainable React components, enhancing UI scalability and developer experience.

Introduction

SVGs (Scalable Vector Graphics) are an essential part of modern UI design. They offer resolution-independent, scalable, and lightweight graphics, making them ideal for icons and illustrations. However, directly embedding SVG code in HTML or JSX can quickly get messy and hard to manage. A more robust and scalable solution is converting SVGs into React components.

This case study walks through how I transformed raw SVG files into reusable and flexible React components, complete with good coding standards and practices. This not only improved maintainability but also enhanced developer experience when building interfaces.


Why Convert SVGs to React Components?

  • Reusability: Wrap SVGs as components that can be reused across your app.
  • Customizability: Easily apply props such as className, style, or override attributes like stroke, fill, and even use text color utilities (like text-red-500) to style SVGs, keeping them consistent with your design system.
  • Type Safety: Leverage TypeScript to ensure proper typing using React.SVGProps.
  • Cleaner Codebase: Keep JSX clean and avoid cluttering files with raw SVG markup.

My Approach

1. Choosing the Source

I started with a set of SVG icons exported from Figma. These icons had inline styles, hardcoded dimensions, and were not optimized for React.

2. Cleaning Up SVG Code

Using tools like SVGO and SVGOMG, I optimized the SVG markup. This removed unnecessary metadata, reduced file size, and standardized formatting.

3. Creating a React Component Wrapper

I chose to use TypeScript for type safety and flexibility. Here's the standard structure I follow:

export default function AppleIcon(props: React.SVGProps<SVGSVGElement>) {
    return (
        <svg
            xmlns="http://www.w3.org/2000/svg"
            width="100%"
            height="100%"
            viewBox="0 0 24 24"
            fill="none"
            stroke="currentColor"
            strokeWidth="2"
            strokeLinecap="round"
            strokeLinejoin="round"
            {...props}
        >
            <path d="M12 20.94c1.5 0 2.75 1.06 4 1.06 3 0 6-8 6-12.22A4.91 4.91 0 0 0 17 5c-2.22 0-4 1.44-5 2-1-.56-2.78-2-5-2a4.9 4.9 0 0 0-5 4.78C2 14 5 22 8 22c1.25 0 2.5-1.06 4-1.06Z"></path>
            <path d="M10 2c1 .5 2 2 2 5"></path>
        </svg>
    );
}

4. Standards I Followed

  • React.SVGProps<SVGSVGElement>: This makes the component flexible by inheriting all standard SVG props.
  • Props Spread ({...props}): Allows consumers to override default props like width, height, stroke, or attach event handlers.
  • Default Dimensions as 100%: So the SVG can inherit size from parent containers.
  • viewBox: Always include this to ensure proper scaling.
  • No hardcoded styles: Styles can now be passed via className or inline styles.
  • Naming Convention: Icons are named as PascalCase with Icon suffix (AppleIcon, SearchIcon, etc.).

Bonus: Auto-generating Icons

If you have a large set of SVGs, consider automating the conversion process with tools like:

  • svgr – Converts SVGs into React components with options for TypeScript, icon mode, and more.
npx @svgr/cli --icon --typescript assets/icons -d src/components/icons

Conclusion

Converting SVGs into React components improved our codebase by making icons more maintainable, customizable, and consistent. With the right standards, naming conventions, and tooling, this becomes a scalable pattern that enhances both performance and developer experience.

If you're working on a design system or a component library, this approach will pay dividends in the long run. Start small, stay consistent, and consider automating the process for even better efficiency.

On this page