nuxt-svg-sprite-icon

Nuxt SVG Sprite Icon
A powerful SVG sprite module for Nuxt 3 & Nuxt 4 that automatically generates SVG sprites from your assets and provides an easy-to-use component for displaying icons.
Features
- ๐ 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
Quick Setup
- 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 โจ
SVG Compatibility
This module has enhanced SVG processing capabilities that handle various types of SVG files:
โ Supported SVG Features
- 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.)
Examples of Supported SVG Types
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.
Configuration
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
}
})
Nuxt 4 Configuration
For Nuxt 4 projects, you can use the new directory structure:
export default defineNuxtConfig({
future: {
compatibilityVersion: 4,
},
modules: ['nuxt-svg-sprite-icon'],
svgSprite: {
// Use app directory for Nuxt 4
input: './app/assets/svg',
output: './app/assets/sprite/gen',
defaultSprite: 'icons',
elementClass: 'svg-icon',
}
})
The module automatically detects Nuxt 4 compatibility mode and adjusts paths accordingly.
Configuration Options
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 |
Component API
SvgIcon Component
The <SvgIcon>
component is automatically registered and available globally.
Props
Prop | Type | Default | Description |
---|---|---|---|
name | string | - | Required. Name of the icon (supports nested paths like user/example ) |
Usage Examples
<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>
File Organization
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" />
Development
# 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
CSS Framework Integration
With UnoCSS/Tailwind CSS
<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>
With Custom CSS
<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>
Troubleshooting
Icons not displaying
- 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
Icons appear as squares
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.
Size control issues
- 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
Performance Considerations
- 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
License
MIT.