Making React SVG integration easy

Yevhenii Viniichuk
3 min readFeb 19, 2021

What this is all about

I've been working with React for the past four years, and usually, there was a lot of boilerplate code related to SVG icons. Each time to add an icon, I'd have to do a few repeatable steps again and again. We wanted to simplify this process, and finally, the most convenient one was invented, which I would like to share with you.

What is the goal

We wanted to make the process of SVG integration easy without losing any of its features:

  • Plug and Play SVG integration.
  • Ability to change color.
  • Responsiveness.
  • No boilerplate code.

Several approaches to use SVG

Let's take a look at the approaches for integrating SVG in React:

1. SVG as Image

We can use SVG as a source to image tag:

const App = () => {
return (
<img src="/images/icons/search.svg" />
)
}

This solution keeps things simple, which is okay. However, the main disadvantage is that we can't change the color "on the fly" because SVG markup is not exposed to the DOM tree.

2. SVG as plain JSX

We can insert SVG code to React "render" method:

const App = () => {
return (
<svg xmlns="<http://www.w3.org/2000/svg>" width="512" height="512" viewBox="0 0 512 512">
<path d="M508.87,478.71,360.14,330a201.64,201.64,0,0,0,45.19-127.31C405.33,90.92,314.42,0,202.67,0S0,90.92,0,202.67,90.92,405.33,202.67,405.33A201.64,201.64,0,0,0,330,360.14L478.71,508.88a10.67,10.67,0,0,0,15.08,0l15.09-15.09A10.66,10.66,0,0,0,508.87,478.71Zm-306.2-116c-88.23,0-160-71.77-160-160s71.77-160,160-160,160,71.77,160,160S290.9,362.67,202.67,362.67Z"
/>
</svg>
)
}

Using this approach, we can do whatever we want with SVG. However, in exchange we have some cons to think about:

  1. We would need to rewrite all attributes to camelCase so React can understand it. Imagine if you have 100-200 icons – it would be a daunting task to make them fit to React.
  2. If we suddenly would need to modify the icon in any graphic editor – we would have to revert our "React SVG" to plain SVG code.
  3. React will process this code. It's redundant in our case; plain HTML works fine.

3. SVG as React Component

This approach is similar to the second one. We can use Webpack loader (like SVGR) to do all "SVG to React" work for us, and the final code might be similar to the following:

import IconChevron from './icon-chevron.svg'

const App = () => <IconChevron />

It seems to be a near-best solution – we can put our SVG in some folder and instantly have React component. Despite that, we cannot pass any custom attributes to this component (like default icon size, color, CSS class).

Developing our approach

We can combine all solutions above to develop the final version:

  • Create the Icon component to handle all icon-related logic in one place.
  1. Add name property to the Icon component.
  2. Based on passed name perform SVG loading during component rendering. It should be imported as a raw string (raw-loader can help with that) and inserted via dangerouslySetInnerHTML.
  • Apply currentColor value to SVG's children to fill property. It makes possible inheritance of color property from the parent.

Usage

Just place your SVG in the same folder with Icon.tsx , pass the SVG's file name to name property of the component, and you're good to go! Let's say you have search.svg:

import { Icon } from './Icon'const HomePage = () => {
return (
<div className="home-page">
<Icon name="search" />
</div>
)
}

To change color of the icon just write some styles:

.icon-search
color: lightblue

You can see the demo by the following link: https://merksam.github.io/examples/webpack-react-svg-icons/

Summarize

I believe this approach can be applied to any library or framework because the main idea is to use raw SVG along with currentColor set on SVG's nested elements, making it library-independent.

Thank you for reading! I would appreciate your feedback so much so we can learn from each other. Together we can make this world better :)

--

--

Yevhenii Viniichuk

I’m a Frontend developer with 10+ years of professional experience