SVG Images as React Components with Webpack

If you’ve ever tried to load inline SVG (using svg-inline-loader) into React, you know it seriously hurts people’s eyes.

import React from 'react' import IconRemove from './icons/remove.svg' const RemoveButton = ( ) = > ( < button > < div dangerouslySetInnerHTML = <!--￼0-- > / > < span > Remove </ span > </ button > )

So what if it looked like this instead?

import React from 'react' import IconRemove from './icons/remove.svg' const RemoveButton = ( ) = > ( < button > < IconRemove /> < span > Remove </ span > </ button > )

Much better, don’t you think?

That’s what svg-react-loader does. It process your SVG file and returns a React component, which is compiled with Babel (more on this below).

Using the Loader ¶

npm install svg-react-loader --save-dev

Refer to Webpack docs for more information on loaders usage. Also, make sure you have installed svg-react-loader’s dependencies.

1. In Module Request ¶

The simplest method, although the configuration convention is preferred. Using svg-react-loader and babel-loader, import your icon just like:

import IconRemove from 'babel!svg-react!./icons/remove.svg'

2. In Webpack Config File (Recommended) ¶

Add in your Webpack configuration file’s loaders array.

{ test : /\.svg$/ , loader : 'babel!svg-react' }

Import your icon just like:

import IconRemove from './icons/remove.svg'

Usage Examples ¶

Loader in module request method (1):

import React from 'react' import IconRemove from 'babel!svg-react!./icons/remove.svg' const RemoveButton = ( ) = > ( < button > < IconRemove /> < span > Remove </ span > </ button > )

Loader in Webpack config file method (2):

import React from 'react' import IconRemove from './icons/remove.svg' const RemoveButton = ( ) = > ( < button > < IconRemove /> < span > Remove </ span > </ button > )

A Note on SVG Loaders ¶

Sometimes, we don’t want all of our SVG files to be loaded as React components. If you use a SVG in a img element, for example, it may lead to conflicts. Fortunately, you can avoid them by being more specific in test regular expression:

{ test : /\.inline.svg$/ , loader : 'babel!svg-react' } , { test : /\.jpe?g$|\.gif$|\.png$|^(?!.*\.inline\.svg$).*\.svg$/ , loader : 'url' }