The best way to use SVG icons in React.
Tags: javascript, react, webdev
Published: 2021-06-25 16:03:51

---
title: The best way to use SVG icons in React.
published: true
description: There are tons of libraries out there that will help you with icons in React, but there's an even easier way.
tags: javascript, react, webdev
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wdj0ks428n3rwt24xkq7.png
---

When I first started working with React, I used libraries like [React Icons](https://react-icons.github.io/react-icons/) or [Bootstrap Icons](https://www.npmjs.com/package/bootstrap-icons) to manage my icons. 

But problems quickly emerged, the first problem is not all of these packages support *tree shaking*. Without tree shaking, when you build your site, all the icons from the library will be included with your build rather than just the ones you use.

The second problem is these libraries can be hard to setup and manage. So what's a better way? Let me show you. If you're new to React you might not know this but in fact you can use *svg icons directly as React components*. So how would we do that?

## Creating a Component

Take this SVG icon (via [Hero Icons](https://heroicons.com/))

![academic svg icon](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zz937dq4u3u0637gvi3h.png)

This SVG icon has the following code:

```js
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
  <path d="M12 14l9-5-9-5-9 5 9 5z" />
  <path d="M12 14l6.16-3.422a12.083 12.083 0 01.665 6.479A11.952 11.952 0 0012 20.055a11.952 11.952 0 00-6.824-2.998 12.078 12.078 0 01.665-6.479L12 14z" />
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 14l9-5-9-5-9 5 9 5zm0 0l6.16-3.422a12.083 12.083 0 01.665 6.479A11.952 11.952 0 0012 20.055a11.952 11.952 0 00-6.824-2.998 12.078 12.078 0 01.665-6.479L12 14zm-4 6v-7.5l4-2.222" />
</svg>
```

The first thing you will want to do is remove the `xmlns` attribute, as it's not used by React when rendering the SVG. Additionally you need to replace the `class` attribute with `className` to make it compliant with React. Your SVG will now look like this:

```js

<svg className="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
  <path d="M12 14l9-5-9-5-9 5 9 5z" />
  <path d="M12 14l6.16-3.422a12.083 12.083 0 01.665 6.479A11.952 11.952 0 0012 20.055a11.952 11.952 0 00-6.824-2.998 12.078 12.078 0 01.665-6.479L12 14z" />
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 14l9-5-9-5-9 5 9 5zm0 0l6.16-3.422a12.083 12.083 0 01.665 6.479A11.952 11.952 0 0012 20.055a11.952 11.952 0 00-6.824-2.998 12.078 12.078 0 01.665-6.479L12 14zm-4 6v-7.5l4-2.222" />
</svg>

```

Now you're ready to create a React component. I suggest creating a functional component.

```jsx
import React from "react";

export const AcademicIcon = () => {
  return (
    <svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
      <path d="M12 14l9-5-9-5-9 5 9 5z" />
      <path d="M12 14l6.16-3.422a12.083 12.083 0 01.665 6.479A11.952 11.952 0 0012 20.055a11.952 11.952 0 00-6.824-2.998 12.078 12.078 0 01.665-6.479L12 14z" />
      <path
        stroke-linecap="round"
        stroke-linejoin="round"
        stroke-width="2"
        d="M12 14l9-5-9-5-9 5 9 5zm0 0l6.16-3.422a12.083 12.083 0 01.665 6.479A11.952 11.952 0 0012 20.055a11.952 11.952 0 00-6.824-2.998 12.078 12.078 0 01.665-6.479L12 14zm-4 6v-7.5l4-2.222"
      />
    </svg>
  );
};

```

At this point you're ready to use the component! You can use it as is in other react components like so:

```jsx
import React from 'react'
import { AcademicIcon } from './AcademicIcon.js'

export const App = () => {
  return (
    <div>
      <AcademicIcon />
    </div>
  )
}

```

## Adding Props

One benefit of using SVG's as React components is you can add props to it just like you would to any other component. Lets add some props to our `AcademicIcon` component to make it more flexible.


```jsx


import React from "react";

export const AcademicIcon = ({ className = "h-6 w-6", fill = "none", stroke = "currentColor", stokeWidth = 2}) => {
  return (
    <svg className={className} fill={fill} viewBox="0 0 24 24" stroke={stroke}>
      <path d="M12 14l9-5-9-5-9 5 9 5z" />
      <path d="M12 14l6.16-3.422a12.083 12.083 0 01.665 6.479A11.952 11.952 0 0012 20.055a11.952 11.952 0 00-6.824-2.998 12.078 12.078 0 01.665-6.479L12 14z" />
      <path
        stroke-linecap="round"
        stroke-linejoin="round"
        stroke-width={strokeWidth}
        d="M12 14l9-5-9-5-9 5 9 5zm0 0l6.16-3.422a12.083 12.083 0 01.665 6.479A11.952 11.952 0 0012 20.055a11.952 11.952 0 00-6.824-2.998 12.078 12.078 0 01.665-6.479L12 14zm-4 6v-7.5l4-2.222"
      />
    </svg>
  );
};


```

Now in this final version we moved `className`, `fill`, `stroke` and `strokeWidth` to a prop and gave it a default of the original value. Now you can call your icon with props:

```jsx
import React from 'react'
import { AcademicIcon } from './AcademicIcon.js'

export const App = () => {
  return (
    <div>
      <AcademicIcon
         className="h-12 w-12"
         fill="red"
         strokeWidth={3}
      />
    </div>
  )
}

```
Because all the props have defaults, you can declare the icon with all the props, some of them or none of them! With this method you are also only loading the icons you are using, no wasteful extra code at build time!

---

If you enjoyed this post check out my other posts on [my blog](https://sunny.gg/post). You should also check out my latest project: [Awesome Devtools](https://awesomedevtools.com?utm_source=blog_post)