Nuxt 3 - SVG Sprite Generation and Usage
Create generate-sprite.ts Install packages like svg-sprite fs and path Create generate-sprite.ts file the root import Sprite from 'svg-sprite'; import { readdirSync, readFileSync } from 'fs'; import { join, basename, extname, relative, resolve } from 'path' import { writeFileSync } from 'fs'; const ICONS_DIR = resolve('assets/icons') // absolute path // npx tsx generate-sprite.ts const sprite = new Sprite({ mode: { symbol: { sprite: 'sprite.svg', example: false }, }, shape: { transform: [ { svgo: { plugins: [ { name: 'removeDimensions', active: false // ❗ Don't remove width/height }, { name: 'removeViewBox', active: false // ❗ Don't remove viewBox } ] } } ], id: { generator: (filepath: string) => { console.log('filepath',filepath) const relPath = relative(ICONS_DIR, resolve(filepath)).replace(/\\/g, '/') const parts = relPath.split('/'); const folder = parts.length > 1 ? parts.slice(0, -1).join('-') : ''; const file = basename(filepath, extname(filepath)); return folder ? `${folder}:${file}` : file; }, }, }, }); function walk(dir: string): string[] { const entries = readdirSync(dir, { withFileTypes: true }); return entries.flatMap((entry) => { const fullPath = join(dir, entry.name); if (entry.isDirectory()) { return walk(fullPath); } else if (entry.isFile() && entry.name.endsWith('.svg')) { return [fullPath]; } return []; }); } async function buildSprite() { const files = walk('assets/icons'); for (const file of files) { console.log('file',file) const content = readFileSync(file, 'utf-8'); sprite.add(file, file, content); console.log('file2') } sprite.compile(async (err, result) => { if (err) { console.error('Compile error:', err); return; } const compiled = result.symbol.sprite.contents; writeFileSync('public/icons/sprite.svg', compiled); console.log('✅ Generated: public/icons/sprite.svg'); }); } buildSprite(); Update ICONS_DIR path. Generate Sprite Run npx tsx generate-sprite.ts How to use?

Create generate-sprite.ts
Install packages like svg-sprite
fs
and path
Create generate-sprite.ts
file the root
import Sprite from 'svg-sprite';
import { readdirSync, readFileSync } from 'fs';
import { join, basename, extname, relative, resolve } from 'path'
import { writeFileSync } from 'fs';
const ICONS_DIR = resolve('assets/icons') // absolute path
// npx tsx generate-sprite.ts
const sprite = new Sprite({
mode: {
symbol: {
sprite: 'sprite.svg',
example: false
},
},
shape: {
transform: [
{
svgo: {
plugins: [
{
name: 'removeDimensions',
active: false // ❗ Don't remove width/height
},
{
name: 'removeViewBox',
active: false // ❗ Don't remove viewBox
}
]
}
}
],
id: {
generator: (filepath: string) => {
console.log('filepath',filepath)
const relPath = relative(ICONS_DIR, resolve(filepath)).replace(/\\/g, '/')
const parts = relPath.split('/');
const folder = parts.length > 1 ? parts.slice(0, -1).join('-') : '';
const file = basename(filepath, extname(filepath));
return folder ? `${folder}:${file}` : file;
},
},
},
});
function walk(dir: string): string[] {
const entries = readdirSync(dir, { withFileTypes: true });
return entries.flatMap((entry) => {
const fullPath = join(dir, entry.name);
if (entry.isDirectory()) {
return walk(fullPath);
} else if (entry.isFile() && entry.name.endsWith('.svg')) {
return [fullPath];
}
return [];
});
}
async function buildSprite() {
const files = walk('assets/icons');
for (const file of files) {
console.log('file',file)
const content = readFileSync(file, 'utf-8');
sprite.add(file, file, content);
console.log('file2')
}
sprite.compile(async (err, result) => {
if (err) {
console.error('Compile error:', err);
return;
}
const compiled = result.symbol.sprite.contents;
writeFileSync('public/icons/sprite.svg', compiled);
console.log('✅ Generated: public/icons/sprite.svg');
});
}
buildSprite();
Update ICONS_DIR
path.
Generate Sprite
Run npx tsx generate-sprite.ts
How to use?
<svg class="icon" >
<use xlink:href="'/icons/sprite.svg#user" crossorigin="anonymous"></use>
</svg>