![]()
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.
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
nuxt-svg-sprite-icon to the modules section of nuxt.config.tsexport default defineNuxtConfig({
modules: [
'nuxt-svg-sprite-icon'
]
})
assets/
svg/
home.svg
search.svg
user/
profile.svg
settings.svg
<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:
<style> tags and CSS classes to inline stylesSVG 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
}
})
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.
| 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>
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.
width and height CSS properties or utility classes like w-6 h-61em, so you can also control size via font-sizew-full h-full on the iconoptimize: true)MIT.