A versatile and lightweight Vite plugin for generating SVG sprites from your SVG files, with support for HMR, SVGO optimization, and flexible configuration options.
- ⚡️ Fast SVG sprite generation
- 🔄 Hot Module Reloading (HMR) support
- 🎨 Preserves important SVG attributes (viewBox, fill, stroke)
- 🛠️ SVGO optimization built-in
- 📁 Multiple icon directory support
- 🔧 Configurable symbol IDs
- 💉 Optional HTML injection
- 📦 File output support
- 👀 Watch mode support
npm i -D @pivanov/vite-plugin-svg-sprite
# or
yarn add -D @pivanov/vite-plugin-svg-sprite
# or
pnpm add -D @pivanov/vite-plugin-svg-sprite
Add the plugin to your vite.config.ts
(or vite.config.js
):
import path from 'path';
import svgSpritePlugin from '@pivanov/vite-plugin-svg-sprite';
export default {
plugins: [
svgSpritePlugin({
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
symbolId: '[dir]-[name]',
svgDomId: 'svg-sprite',
inject: 'body-last',
}),
],
};
You can use the generated sprites in two ways:
- Direct Import (when not using inject option):
import svgSpriteString from 'virtual:svg-sprite';
const container = document.createElement('div');
const shadow = container.attachShadow({ mode: 'open' });
const sprite = new DOMParser()
.parseFromString(svgSpriteString, 'image/svg+xml')
.documentElement;
shadow.appendChild(sprite);
document.body.appendChild(container);
- Reference in HTML (works with both methods):
<svg>
<use href="#icons-home" />
</svg>
Option | Type | Default | Description |
---|---|---|---|
iconDirs |
string[] |
Required | Directories containing SVG files to be processed into sprites |
symbolId |
string |
[dir]-[name] |
Format for symbol IDs. Uses placeholders: [dir] (directory name) and [name] (file name without extension). Example: [dir]-[name] for icons/home.svg becomes icons-home |
svgDomId |
string |
svg-sprite |
ID attribute for the root SVG sprite element in the DOM |
inject |
'body-last' | 'body-first' |
undefined |
Controls where the sprite is injected in the HTML. body-first injects at start of body, body-last at the end |
svgoConfig |
object |
See SVGO section | Configuration for SVGO optimization. Override default settings for SVG optimization |
fileName |
string |
undefined |
If provided, saves the sprite to a file instead of injecting it. Example: sprite.svg |
verbose |
boolean |
true |
Enable/disable detailed logging output during plugin operation |
The plugin comes with optimized SVGO defaults:
{
plugins: [
{
name: 'preset-default',
params: {
overrides: {
removeViewBox: false,
removeUnknownsAndDefaults: {
defaultAttrs: false,
},
cleanupIds: {
minify: false,
},
mergePaths: false,
},
},
},
{
name: 'removeAttributesBySelector',
params: {
selectors: [
{
selector: '*:not(svg)',
preserve: ['stroke*', 'fill*'],
},
],
},
},
],
}
svgSpritePlugin({
iconDirs: ['src/icons'],
symbolId: 'icon-[name]',
inject: 'body-last'
})
svgSpritePlugin({
iconDirs: ['src/icons'],
symbolId: 'icon-[name]',
fileName: 'sprite.svg'
})
svgSpritePlugin({
iconDirs: ['src/icons'],
symbolId: 'icon-[name]',
svgoConfig: {
plugins: [
{
name: 'removeAttrs',
params: { attrs: '(fill|stroke)' }
}
]
}
})
The plugin generates a sprite that looks like this:
<svg xmlns="http://www.w3.org/2000/svg" style="position:absolute;width:0;height:0;" id="svg-sprite">
<defs>
<!-- Collected definitions from SVGs -->
</defs>
<symbol id="icons-home" viewBox="0 0 24 24">
<!-- SVG content -->
</symbol>
<!-- More symbols... -->
</svg>
Created by pivanov
MIT