vite-svg-sprite-generator-plugin
v1.3.1
Published
Production-ready Vite plugin for automatic SVG sprite generation with HMR support, SVGO optimization, security features, and tree-shaking
Maintainers
Readme
🎨 Vite SVG Sprite Generator Plugin
Production-ready Vite plugin for automatic SVG sprite generation with HMR, tree-shaking, and SVGO optimization
The Problem: Using separate SVG files creates multiple HTTP requests. Inline SVG in HTML duplicates code and bloats your markup. Creating and maintaining SVG sprites manually is tedious and error-prone.
The Solution: This plugin automatically generates an optimized SVG sprite from your icons folder and injects it directly into HTML. Works in dev mode with HMR — edit an icon → see changes instantly without page reload. Tree-shaking removes unused icons in production (up to 84% reduction).
Features
- 2-3x faster builds - Parallel SVG processing (v1.3.0+)
- Tree-shaking - Remove unused icons (up to 84% reduction)
- HMR - Instant icon updates without page reload
- SVGO optimization - 40-60% smaller sprites
- Security - XSS & path traversal protection
- Zero config - Works out of the box
- Framework agnostic - React, Vue, Svelte, any Vite project
- Multi-page support - Works with vite-multi-page-html-generator-plugin
Installation
npm install -D vite-svg-sprite-generator-plugin
# Optional: SVGO for optimization (recommended)
npm install -D svgoQuick Start
1. Configure Vite
// vite.config.js
import { defineConfig } from 'vite';
import svgSpritePlugin from 'vite-svg-sprite-generator-plugin';
export default defineConfig({
plugins: [svgSpritePlugin()]
});2. Add SVG Icons
src/
icons/
home.svg
user.svg
search.svg3. Use Icons
<svg class="icon">
<use href="#home" />
</svg>.icon {
width: 24px;
height: 24px;
fill: currentColor;
}Configuration
interface SvgSpriteOptions {
iconsFolder?: string; // Default: 'src/icons'
spriteId?: string; // Default: 'sprite-id'
spriteClass?: string; // Default: 'sprite-class'
idPrefix?: string; // Default: ''
watch?: boolean; // Default: true (dev)
debounceDelay?: number; // Default: 100ms
verbose?: boolean; // Default: true (dev)
svgoOptimize?: boolean; // Default: true (production)
svgoConfig?: object; // Custom SVGO config
currentColor?: boolean; // Default: true
treeShaking?: boolean; // Default: false
scanExtensions?: string[]; // Default: ['.html', '.js', '.ts', '.jsx', '.tsx', '.vue', '.svelte']
}Basic Example
svgSpritePlugin({
iconsFolder: 'src/icons',
treeShaking: true,
verbose: true
})Production Optimized
svgSpritePlugin({
iconsFolder: 'src/icons',
treeShaking: true, // Remove unused icons
svgoOptimize: true, // Optimize SVG
currentColor: true // CSS color control
})Framework Support
| Framework | Status | Notes |
|-----------|--------|-------|
| Vite + React | ✅ Full | Examples |
| Vite + Vue 3 | ✅ Full | Examples |
| Vite + Svelte | ✅ Full | Examples |
| Nuxt 3 (SPA) | ✅ Full | Set ssr: false |
| Nuxt 3 (SSR) | ⚠️ Partial | SSR Guide |
| SvelteKit | ⚠️ Partial | SSR limitations |
| Next.js | ❌ No | Uses Webpack, not Vite |
| Create React App | ❌ No | Uses Webpack, not Vite |
Rule of thumb: Works with Vite ✅ | Doesn't work with Webpack ❌
React Example
export function Icon({ name, size = 24 }) {
return (
<svg width={size} height={size}>
<use href={`#${name}`} />
</svg>
);
}
// Usage
<Icon name="home" />See complete framework examples.
Key Features
Tree-Shaking
Remove unused icons from production builds:
svgSpritePlugin({
treeShaking: true // Enable tree-shaking
})How it works:
- Scans codebase for
<use href="#iconId"> - Finds used icons in HTML/JS/TS/JSX/TSX/Vue/Svelte
- Removes unused icons from production
- Keeps all icons in dev for better DX
Results:
50 total icons → 8 used (42 removed, 84% reduction)
Bundle: 45.2 KB → 7.8 KBPer-page optimization: In multi-page apps, each HTML page gets only its icons.
Hot Module Replacement
Changes to SVG files trigger instant updates without page reload:
🔄 SVG files changed, regenerating sprite...
✅ HMR: Sprite updated with 10 iconsSecurity
Automatic protection against:
- XSS attacks - Removes
<script>, event handlers,javascript:URLs - Path traversal - Validates icon folder paths
- Malicious content - Sanitizes all SVG before injection
Multi-Page Projects
Works seamlessly with vite-multi-page-html-generator-plugin:
export default defineConfig({
plugins: [
multiPagePlugin({
pagesDir: 'src/pages'
}),
svgSpritePlugin({
treeShaking: true // Each page gets only its icons
})
]
});Performance
Build Time (v1.3.0)
| Icons | v1.2.1 | v1.3.0 | Speedup | |-------|--------|--------|---------| | 50 | 850ms | 420ms | 2.0x ⚡ | | 100 | 1.7s | 810ms | 2.1x ⚡ | | 200 | 3.4s | 1.5s | 2.3x ⚡ |
Bundle Size (with tree-shaking)
Project: 50 icons total, 8 used
Before: 45.2 KB (all icons)
After: 7.8 KB (used only)
Saving: 37.4 KB (83% reduction)SVGO Optimization
Average reduction: 40-60%
Example:
clock.svg: 317 → 228 bytes (-28%)
layers.svg: 330 → 156 bytes (-53%)How It Works
The plugin automatically injects the sprite into your HTML:
<body>
<!-- Injected automatically -->
<svg id="sprite-id" style="display: none;">
<symbol id="home" viewBox="0 0 24 24">...</symbol>
<symbol id="user" viewBox="0 0 24 24">...</symbol>
</svg>
<!-- Your app -->
<div id="app"></div>
</body>Benefits:
- No separate file requests
- Instant rendering
- Single HTTP request
- Works with SSR/SSG
Advanced
Vite Integration
Uses official Vite APIs:
enforce: 'pre'- Run before core pluginsapply()- Conditional executioncreateFilter()- Standard file filtering- HMR API - Hot module replacement
Plugin Hooks
{
configResolved() { // Validate paths
buildStart() { // Generate sprite
transformIndexHtml() { // Inject into HTML
configureServer() { // Setup HMR
buildEnd() { // Cleanup
}Optimizations
- Parallel SVG processing
- mtime-based caching
- Debounced HMR
- Tree-shaking
- SVGO compression
Compatibility
- Vite: 4.x, 5.x, 6.x, 7.x
- Node.js: 14.18.0+
- TypeScript: Full support
- OS: Windows, macOS, Linux
Links
Documentation
Related Plugins
- vite-multi-page-html-generator-plugin - Multi-page static site generator
License
MIT © Karev G.S.
Made with ❤️ for the Vite ecosystem
