Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I load SVGs directly in my React component using webpack?

I would like to render a material design icon directly in my NextButton component using webpack. Here's the relevant part of my code:

var NextIcon = require('material-design-icons/navigation/svg/production/ic_chevron_right_18px.svg');

var NextButton = React.createClass({
  render: function() {
    return (
      <Link to={this.props.target} className='button--next'>
        {this.props.label} {NextIcon}
      </Link>
    )
  }
});

But this isn't working as I thought it would. It seems to output the svg as a string, rather than an element.

I've tried using raw-loader, img-loader, url-loader, file-loader and svg-loader but I can't find the correct way to do this.

like image 635
dduupp Avatar asked Jun 15 '15 11:06

dduupp


People also ask

How do I import SVG into react component?

To do this, open up the SVG file in a text editor, and copy-paste the code into a new component: export const ArrowUndo = () => { return ( <svg xmlns="http://www.w3.org/2000/svg" className="ionicon" viewBox="0 0 512 512" > <path d="M245.


1 Answers

Since your SVG content is stored as a string and not as a React element, you'll need to use Dangerously Set innerHTML.

var NextIcon = require('material-design-icons/navigation/svg/production/ic_chevron_right_18px.svg');

var NextButton = React.createClass({
  render: function() {
    return (
      <Link to={this.props.target} className='button--next'>
        {this.props.label} <span dangerouslySetInnerHTML={{ __html: NextIcon }} />
      </Link>
    )
  }
});

You could perhaps work your way around this by creating a webpack loader that automatically does this for you whenever you require a SVG file.

dangerouslySetInnerHTML.loader.js

module.exports = function(content) {
    return (
        'module.exports = require("react").createElement("span", {' +
            'dangerouslySetInnerHTML: {' +
                '__html: ' + JSON.stringify(content) +
            '}' +
        '});'
    );
};

webpack.config.js

loaders: [
  {
    test: /\.svg$/,
    loader: require.resolve('./dangerouslySetInnerHTML.loader'),
    exclude: /node_modules/,
  },
],

The previous code snippet would then become:

var NextIcon = require('material-design-icons/navigation/svg/production/ic_chevron_right_18px.svg');

var NextButton = React.createClass({
  render: function() {
    return (
      <Link to={this.props.target} className='button--next'>
        {this.props.label} {NextIcon}
      </Link>
    )
  }
});
like image 160
Alexandre Kirszenberg Avatar answered Sep 28 '22 00:09

Alexandre Kirszenberg