The BVG Software website is 🚧 UNDER CONSTRUCTION 🚧

Blog.

React SVG Icons With No Artistic Ablility

Cover Image for React SVG Icons With No Artistic Ablility
BVG Software
•
10 Min Read

Are you sick of the same old icons you have been using in your projects lately? Do you lack the artistic ability to draw a stick figure? If you answered yes (or no), please continue reading.

My SVG Issue

Since I began building things with JavaScript I have been using essentially the same icon set over and over. I often work with React and Styled Components so my go-to icon library has been Styled Icons. Styled Icons contains the same familiar icon sets we have probably all used at some point: Font Awesome, Material Design, Boxicons, etc. Even though there are thousands of choices and all of these icon collections are great in their own right, I got to the point where I couldn't find the right icons for my use cases and all my projects sort of looked the same. I thought creating my own icon set was way out of reach due to my complete lack of artistic talent. Turns out I was wrong.

Example Boxicons Chromium icon

The solution to my problem was Scalable Vector Graphics, or SVG. To get started, all that is required is some kind of SVG editor. Here is a list of 7 free SVG editors. My personal preference is Boxy SVG, but I haven't tried any others 🙄.

The great part about working with SVGs is that mathematical skills are just as important than artistic skills. Boxy SVG has a ton of settings and taking the time to familiarize yourself with them is worthwhile. Here are the basic steps I take to create my icons.

How I Design Custom SVG Icons

Step 1 - Draw an icon

  • Change the dimensions of the canvas to 50px by 50px
  • Geometry options help size and position elements
  • Backgrounds will be transparent unless you set the fill attribute
I used the Circle and the Pie tool to create this

Hints

  • Make one 120 degree pie piece
  • Copy and Paste it two times
  • Rotate the pieces to fit
  • Put a circle on top of that
  • The inner circle has a 1px white stroke
  • Match colors with a Color Dropper Tool

Step 2 - Optimize your SVG

  • Save your icon as an svg file
  • Go to OMGSVG and open your file. This web app is a cool utility that simplifies the markup required to render your svg.
  • Change settings and toggle the Show Original button to see the difference
  • Image / Markup tabs while both change based on settings
  • I generally use the default settings including Prettify Markup but customize when needed

The more complex your SVG the more dramatic the optimization

Original

Original SVG markup before optimizationOriginal SVG markup before optimization

Optimized

Optimized SVG markup after optimizationOptimized SVG markup after optimization

An SVG remains sharp despite scaling up size

  • Copy and Paste markup into your project
  • Drop all the xmln stuff since we are using these with inline HTML
  • Add a width attribute to the SVG or use CSS to style
// Cleaned up SVG markup
<svg width='200' viewBox='0 0 50 50'>
  <path
    d='M15.362 4.281a23 23 0 0 1 32.478 23.07l-22.898-2.16z'
    fill='#e94435'
  />
  <path
    d='M47.882 27.292a23 23 0 0 1-36.496 15.97l13.638-18.52z'
    fill='#35a755'
  />
  <path
    d='M11.569 43.37a23 23 0 0 1 4.762-39.552l9.037 21.15z'
    fill='#fabd05'
  />
  <circle cx='25' cy='25' r='8' stroke='#fff' fill='#3f84f3' />
</svg>

Step 3 - Create a Reusable React Component

One benefit of React is component reusability. We can leverage the functional nature of react to parameterize the name of an icon. This essentially abstracts the SVG markup into a single file and we can represent icons throughout an application with <Svg name='google' />.

  • Svg component will take name as props
  • The name prop will tell Svg what markup to return
  • Use React.Fragment shorthand <></> to return output
Svg.js
import React from 'react'

// Pass any additional props via destructuring ...rest
function Svg({ name, ...rest }) {
  // Helper function to return inner svg elements
  // Each icon has its own case
  // Throws error if no name prop is present
  const getPath = (n) => {
    switch (n) {
      case 'google':
        return (
          <>
            <path
              d='M15.362 4.281a23 23 0 0 1 32.478 23.07l-22.898-2.16z'
              fill='#e94435'
            />
            <path
              d='M47.882 27.292a23 23 0 0 1-36.496 15.97l13.638-18.52z'
              fill='#35a755'
            />
            <path
              d='M11.569 43.37a23 23 0 0 1 4.762-39.552l9.037 21.15z'
              fill='#fabd05'
            />
            <circle cx='25' cy='25' r='8' stroke='#fff' fill='#3f84f3' />
          </>
        )
      default:
        throw Error('name is required!')
    }
  }

  return (
    <svg viewBox='0 0 50 50' {...rest}>
      {getPath(name)}
    </svg>
  )
}

export default Svg
  • Add as many icons as you need
  • Use like any other React component

Step 4 - Other Ideas

  • Set size via passing a width / height prop or via CSS. Be creative here.
  • Pass fill or stroke as a prop to change up colors

A couple small changes and we have the Chromium icon

  • To simplify the concept lets add a dot icon
Svg.js
function Svg({ name, fill = 'black' }) {
  const getPath = (n) => {
    switch (n) {
      case 'dot':
        return (
          <>
            <circle cx='25' cy='25' r='8' fill={fill} />
          </>
        )
      case 'google':
        return (
          <>
            <path
              d='M15.362 4.281a23 23 0 0 1 32.478 23.07l-22.898-2.16z'
              fill='#e94435'
            />
            <path
              d='M47.882 27.292a23 23 0 0 1-36.496 15.97l13.638-18.52z'
              fill='#35a755'
            />
            <path
              d='M11.569 43.37a23 23 0 0 1 4.762-39.552l9.037 21.15z'
              fill='#fabd05'
            />
            <circle cx='25' cy='25' r='8' stroke='#fff' fill='#3f84f3' />
          </>
        )
      default:
        throw Error('name is required!')
    }
  }

  return <svg viewBox='0 0 50 50'>{getPath(name)}</svg>
}

Pass in a fill prop. Note the use of a default parameter so we don't get errors if fill is omitted.

<>
  <Svg name='dot' />
  <Svg name='dot' fill='rebeccapurple' />
  <Svg name='dot' fill='orangered' />
  <Svg name='dot' fill='greenyellow' />
</>

In Closing

Now you know how to make your own icons and turn them into a simple and reuseable React component. Hopefully, you agree with my premise that minimal artistic ability is required. I could even argue that the most important skill is understanding the features of your SVG editor.

There is a time investment here but I use working on these icons as a break from the more mind crunching code of my projects. I think the end results are websites and applications that look more authentic and are more engaging for the user.


**Examples From My Last Project