A powerful SVG sprite module for Nuxt 3 that automatically generates SVG sprites from your assets and provides an easy-to-use component for displaying icons.
- 🚀 Auto-generated SVG sprites - Automatically scans and converts SVG files to sprite format
- 📁 Nested folder support - Organize your icons in folders for better structure
- 🎨 CSS-only styling - Full control over appearance using CSS classes
- ⚡ Hot reload - Development mode file watching for instant updates
- 🎯 TypeScript support - Full type safety out of the box
- 🌈 Framework agnostic - Works seamlessly with UnoCSS, Tailwind, or any CSS framework
- 📦 Zero configuration - Works out of the box with sensible defaults
- 🪶 Lightweight - Minimal API surface with maximum flexibility
- 🔧 Enhanced SVG compatibility - Handles complex SVGs with styles, IDs, and defs
- Add
nuxt-svg-sprite-icon
dependency to your project
# Using pnpm
pnpm add -D nuxt-svg-sprite-icon
# Using yarn
yarn add --dev nuxt-svg-sprite-icon
# Using npm
npm install --save-dev nuxt-svg-sprite-icon
- Add
nuxt-svg-sprite-icon
to themodules
section ofnuxt.config.ts
export default defineNuxtConfig({
modules: [
'nuxt-svg-sprite-icon'
]
})
- Create your SVG assets directory and add some SVG files
assets/
svg/
home.svg
search.svg
user/
profile.svg
settings.svg
- Use the SVG icons in your components
<template>
<div>
<!-- Basic usage -->
<SvgIcon name="home" />
<!-- With CSS classes -->
<SvgIcon name="home" class="w-6 h-6 text-blue-500" />
<!-- Nested folder -->
<SvgIcon name="user/profile" class="w-8 h-8 fill-green-500" />
<!-- Container approach -->
<div class="w-100px h-100px">
<SvgIcon name="search" class="w-full h-full fill-red-500" />
</div>
</div>
</template>
That's it! You can now use SVG icons with complete CSS control ✨
This module has enhanced SVG processing capabilities that handle various types of SVG files:
-
Inline styles and CSS classes - Automatically converts
<style>
tags and CSS classes to inline styles - Complex defs and gradients - Preserves functional definitions like clipPaths, gradients, and patterns
- ID conflict resolution - Automatically prefixes IDs to prevent conflicts between different sprites
- Various SVG formats - Works with SVGs from different design tools (Figma, Sketch, Illustrator, etc.)
SVG with CSS styles:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19.721 17.39">
<defs>
<style>
.cls-1{fill:#fff}
</style>
</defs>
<path class="cls-1" d="M0 6.3L6 11..."/>
</svg>
SVG with inline fills:
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<path fill="white" d="M9.84375 16.0469V19.1178..."/>
</svg>
SVG with clipPaths and complex defs:
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0)">
<path fill="white" d="..."/>
</g>
<defs>
<clipPath id="clip0">
<rect width="24" height="24"/>
</clipPath>
</defs>
</svg>
All these formats are automatically processed and optimized for use in sprite systems while maintaining visual fidelity.
You can configure the module by adding a svgSprite
section to your nuxt.config.ts
:
export default defineNuxtConfig({
modules: ['nuxt-svg-sprite-icon'],
svgSprite: {
// Source directory for SVG files
input: '~/assets/svg',
// Output directory for generated sprites
output: '~/assets/sprite/gen',
// Default sprite name (for files in root of input directory)
defaultSprite: 'icons',
// Global CSS class for all svg-icon instances
elementClass: 'svg-icon',
// Whether to optimize SVG files (requires svgo)
optimize: false
}
})
Option | Type | Default | Description |
---|---|---|---|
input |
string |
'~/assets/svg' |
Directory containing original SVG files |
output |
string |
'~/assets/sprite/gen' |
Directory for generated sprite files |
defaultSprite |
string |
'icons' |
Name of default sprite (for SVGs in root input directory) |
elementClass |
string |
'svg-icon' |
Global CSS class applied to all <SvgIcon> elements |
optimize |
boolean |
false |
Enable SVG optimization using SVGO |
The <SvgIcon>
component is automatically registered and available globally.
Prop | Type | Default | Description |
---|---|---|---|
name |
string |
- |
Required. Name of the icon (supports nested paths like user/example ) |
<template>
<!-- Basic usage with default 1em size -->
<SvgIcon name="home" />
<!-- Control size with CSS classes -->
<SvgIcon name="home" class="w-6 h-6" />
<SvgIcon name="home" class="w-8 h-8" />
<!-- Control size with font-size -->
<SvgIcon name="home" class="text-2xl" />
<SvgIcon name="home" style="font-size: 3rem;" />
<!-- Control color -->
<SvgIcon name="home" class="text-blue-500" />
<SvgIcon name="home" class="fill-red-600" />
<!-- Nested folder icons -->
<SvgIcon name="user/profile" class="w-10 h-10 text-green-500" />
<!-- Container-based sizing -->
<div class="w-20 h-20">
<SvgIcon name="search" class="w-full h-full fill-purple-500" />
</div>
<!-- Custom styles -->
<SvgIcon name="home" class="custom-icon" />
<!-- Interactive states -->
<SvgIcon
name="home"
class="w-8 h-8 text-blue-500 hover:text-blue-700 transition-colors cursor-pointer"
/>
<!-- Responsive sizing -->
<SvgIcon name="home" class="w-4 h-4 md:w-6 md:h-6 lg:w-8 lg:h-8" />
</template>
<style scoped>
.custom-icon {
width: 3rem;
height: 3rem;
color: #3b82f6;
transition: all 0.2s ease;
}
.custom-icon:hover {
color: #1d4ed8;
transform: scale(1.1);
}
</style>
The module supports nested folder structures:
assets/svg/
├── home.svg → <SvgIcon name="home" />
├── search.svg → <SvgIcon name="search" />
├── user/
│ ├── profile.svg → <SvgIcon name="user/profile" />
│ └── settings.svg → <SvgIcon name="user/settings" />
└── admin/
├── dashboard.svg → <SvgIcon name="admin/dashboard" />
└── users.svg → <SvgIcon name="admin/users" />
# Install dependencies
npm install
# Generate type stubs and prepare development environment
npm run dev:prepare
# Develop with the playground
npm run dev
# Build the playground
npm run dev:build
# Build the module
npm run prepack
# Run type checking
npm run test:types
# Release new version
npm run release
<template>
<!-- Size control -->
<SvgIcon name="home" class="w-6 h-6" />
<SvgIcon name="home" class="w-8 h-8" />
<!-- Color control -->
<SvgIcon name="home" class="text-blue-500" />
<SvgIcon name="home" class="fill-red-600" />
<!-- Combined styling -->
<SvgIcon
name="user/profile"
class="w-10 h-10 text-green-500 hover:text-green-700 transition-all duration-200"
/>
<!-- Responsive design -->
<SvgIcon name="home" class="w-4 h-4 sm:w-6 sm:h-6 lg:w-8 lg:h-8" />
<!-- Container-based approach -->
<div class="w-16 h-16 bg-gray-100 rounded-full flex items-center justify-center">
<SvgIcon name="home" class="w-8 h-8 text-gray-600" />
</div>
</template>
<template>
<SvgIcon name="home" class="icon-large" />
<SvgIcon name="user/profile" class="icon-animated" />
</template>
<style scoped>
.icon-large {
width: 4rem;
height: 4rem;
color: #3b82f6;
}
.icon-animated {
width: 2rem;
height: 2rem;
transition: transform 0.3s ease;
}
.icon-animated:hover {
transform: rotate(180deg) scale(1.2);
}
</style>
- Check file paths: Ensure your SVG files are in the correct directory
- Verify build: Make sure the module generated sprite files in your output directory
- Check console: Look for any error messages in the browser console
- Restart dev server: Try restarting your development server
This usually indicates that the SVG files have incorrect or missing viewBox
attributes. The module attempts to extract or generate appropriate viewBox values, but you may need to manually fix your SVG files.
- Use
width
andheight
CSS properties or utility classes likew-6 h-6
- The default size is
1em
, so you can also control size viafont-size
- For container-based sizing, use
w-full h-full
on the icon
- All sprites are injected into the DOM on page load
- For large icon sets, consider organizing icons into different folders/sprites
- SVG optimization can help reduce file sizes (enable with
optimize: true
) - The CSS-only approach means no JavaScript is needed for styling
MIT.