how to set up an inline svg with webpack
I am wondering how to set up an inline svg with webpack?
I am following the react-webpack-cookbook.
I have my webpack.config set up correctly with the file loader.
However the example shows using a background image like this:
.icon {
background-image: url(./logo.svg);
}
which works fine, but I want to have an inline svg image how do I do this to include my logo.svg inline in my react component?
import React, { Component } from 'react'
class Header extends Component {
render() {
return (
<div className='header'>
<img src={'./logo.svg'} />
</div>
);
}
};
export default Header
Solution 1:
Actually Michelle's answer pointed me in the right direction, and that works nicely for loading an svg file with webpack and using it as your <img>
src
However to actually get the inline svg, I needed to do the following:
Instead of file-loader use svg-inline-loader as your svg loader:
{ test: /\.svg$/, loader: 'svg-inline-loader' }
Then to load the svg inline in a component:
import React, { Component } from 'react'
import logo from "./logo.svg";
class Header extends Component {
render() {
return (
<div className='header'>
<span dangerouslySetInnerHTML={{__html: logo}} />
</div>
);
}
};
export default Header
It looks like there is an inline svg wrapper for react svg-inline-react which would be another option instead of the <div dangerouslySetInnerHTML={{__html: mySvg}} />
Solution 2:
Here is a simple non-react solution.
- Install Svg inline loader
- In webpack.config.js add
{ test: /\.svg$/, loader: 'svg-inline-loader' }
- In your js file import svg image and add it to a DOM element like so
import Svg from './svg.svg';
function component() {
const element = document.createElement('div');
element.innerHTML = Svg;
return element;
}
document.body.appendChild(component());
Solution 3:
I hope my late answer will still be useful for someone, because I don't like any of abovementioned options.
The react-svg-loader webpack loader allows you to import SVG icons like JSX components:
import Logo from './logo.svg';
class App extends Component {
render() {
return (
<div className="App">
<Logo fill="red" className="logo" width={50} height={50} />
</div>
);
}
}
and minimum config looks like this:
{
test: /\.svg$/,
use: [
{
loader: "babel-loader"
},
{
loader: "react-svg-loader",
options: {
jsx: true // true outputs JSX tags
}
}
]
}
The best part is that it just outputs the svg file contents, without any extra wrappers and dangerouslySetInnerHTML
in your code.
Solution 4:
Old question, but I didn't see this solution anywhere so I decided to post it, hoping it will help someone.
If you want to be able to style those SVG icons, you might want to load them with the raw loader:
webpack.config.js:
{
test: /\.svg$/,
loader: 'raw-loader'
}
The import in my view:
import closeIcon from 'svg/ic_close_black_24px.svg';
The template (Mustache uses 3 brackets to insert the SVG data (URL)unencoded):
<button id="closeModal">
{{{closeIcon}}}
</button>
this way the SVG data will be inserted instead of the brackets and look like this:
<button id="closeModal">
<svg fill="#000000" height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"></path>
<path d="M0 0h24v24H0z" fill="none"></path>
</svg>
</button>
I'm using Backbone with Mustache template engine with Webpack 2.5.1
Solution 5:
If I'm not mistaken, since you're using the file loader, you can utilize it in much the same way as any other require. Webpack will turn require("./logo.svg")
into a path to a file, which it will emit when it bundles.
import React, { Component } from 'react'
import mySvg from './logo.svg'
class Header extends Component {
render() {
return (
<div className='header'>
<img src={mySvg} />
</div>
);
}
};
export default Header