React SVG Icons With No Artistic Abilities
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.
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 Adobe Illustrator is also a solid program.
The great part about working with SVG is that mathematical skills can be 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
I used the Circle and the Pie tool to create this
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
- 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
- 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
- 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 takename
as props- The
name
prop will tellSvg
what markup to return - Use
React.Fragment
shorthand<></>
- Add as many icons as you need
- Use like any other React component
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
Step 4 - Using React Props
- Set size via passing a
width
/height
prop or via CSS - Pass
fill
orstroke
as a prop to change colors - Check out these Chromium icons
Step 5 - Add More Icon Names
- Add
dot
as a new case in aswitch
statement - Return a basic
circle
- Pass
fill
as a props - Set black as a default parameter
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>
}
<>
<Svg name='dot' />
<Svg name='dot' fill='rebeccapurple' />
<Svg name='dot' fill='orangered' />
<Svg name='dot' fill='greenyellow' />
</>
Final Thoughts
Now you know how to make your own icons and turn them into a simple and reusable 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.