It's like style-loader, but for SVGs. Features:
- Create a single SVG sprite from a set of images
- Raster image support (PNG, JPG and GIF)
- Custom sprite implementations
When you require an image, SVG sprite webpack loader will transform it into an SVG symbol and add it to the array using a special sprite class.
When the browser event DOMContentLoaded
fires, an image sprite will then be rendered and injected as the first child of document.body
.
By default, require statements like require('svg-sprite!./image.svg')
will return a symbol ID, so you can reference it later
with SVG's <use>
tag:
<svg>
<use xlink:href="#id" />
</svg>
Raster images will be inlined (using base64) and wrapped with an <image>
tag.
Files like image@2x.png
will be transformed with proper scale.
If you need custom behavior, use the spriteModule
config option to specify the path of your sprite implementation module.
You can extend a default lib/web/sprite.js
, or create your own.
In the latter case you only need to implement the add
method that accepts the symbol data as a string.
npm install svg-sprite-loader --save-dev
module.exports = {
module: {
loaders: [{
test: /\.svg$/,
loader: 'svg-sprite?' + JSON.stringify({
name: '[name]_[hash]',
prefixize: true,
spriteModule: 'utils/my-custom-sprite'
})
}]
}
};
or, using regular expressions to capture the SVG's filename:
module.exports = {
module: {
loaders: [{
test: /\.svg$/,
loader: 'svg-sprite?' + JSON.stringify({
name: 'icon-[1]',
prefixize: true,
regExp: './my-folder/(.*)\\.svg'
})
}]
}
};
// path-to-project/my-folder/name.svg > #icon-name
name
configures a custom symbol ID name. Default is[name]
. The following name patterns are supported:[ext]
- the extension of the image[name]
- the basename of the image[path]
- the path of the image[hash]
- the hash or the image content[pathhash]
- the hash or the image path
angularBaseWorkaround
adds a workaround for Angular.js 1.x issues with combining<base>
and the history API (which is typical for Angular.js). Default isfalse
.prefixize
isolates an image content by prefixing itsid
,xlink:href
andurl(#id)
elements. Default istrue
.spriteModule
defines custom sprite implementation module pathesModule
configures whether to transpile the module to an ES-compatible format. When this option is set totrue
, the loader will producemodule.exports.__esModule = true; module.exports['default'] = svg
. Default isfalse
. (This is useful for transpilers other than Babel.)
SVG Sprite Loader works well with the <base>
tag in normal cases, however, in situations where the <base>
tag is used with the browser's history
API to simulate location changing, this will often break SVG xlink:href
inclusion.
There are a few ways to get around this:
- If you use Angular.js 1.x, simply enable the
angularBaseWorkaround
config option described above - If you use Angular 2.x or newer, you can remove the
<base>
tag and provide the router with an appropriateAPP_BASE_HREF
value - If you're using another framework, you have to:
- resolve the full image URL using
window.location
(so its usage may look like<use xlink:href="https://yoursite.com/your/full/path#id">
), - trigger the
spriteLoaderLocationUpdated
event when a new location has been loaded. TheangularBaseWorkaround
option is one example of this implementation.
- resolve the full image URL using
Single image:
var id = require('svg-sprite!./image.svg');
// => 'image'
Set of images:
var files = require.context('svg-sprite!images/logos', false, /(twitter|facebook|youtube)\.svg$/);
files.keys().forEach(files);
Custom sprite behavior:
// my-sprite.js
var Sprite = require('node_modules/svg-sprite-loader/lib/web/sprite');
module.exports = new Sprite();
// my-app.jsx
var sprite = require('my-sprite');
class MyApplication extends React.Component {
componentWillMount() {
sprite.elem = sprite.render(document.body);
}
componentWillUnmount() {
sprite.elem.parentNode.removeChild(sprite.elem);
}
}
Using with React:
// icon.jsx
var GLYPHS = {
PONY: require('img/pony.svg'),
UNICORN: require('img/unicorn.svg')
};
class Icon extends React.Component {
render() {
var glyph = this.props.glyph;
return (
<svg className="icon" dangerouslySetInnerHTML={{__html: '<use xlink:href="' + glyph + '"></use>'}}/>
)
}
}
module.exports = Icon;
module.exports.GLYPHS = GLYPHS;
// some-component.jsx
var Icon = require('components/icon');
<Icon glyph={Icon.GLYPHS.UNICORN}>
Using with React 0.14+:
// icon.jsx
export default function Icon({glyph, width = 16 , height = 16, className = 'icon'}){
return (
<svg className={className} width={width} height={height}>
<use xlinkHref={glyph} />
</svg>
);
}
// some-component.jsx
import Icon from './icon';
import help from './images/icons/Help.svg';
<Icon glyph={help} />