An easy and performant way to use SVG icons in your Nuxt 3 app.
Automatically creates
SVG <symbol>
sprites
during the build and provides components and composables to use these icons.
- Aggregate all SVG files into one or more sprite files
- Reduce bundle size and SSR-rendered page size
- Full HMR support
- Provides
<SpriteSymbol>
component to render<svg>
with<use>
- Provides
<SpriteSymbolInline>
component to inline the SVG - Loads the sprite.svg from URL (/_nuxt/sprite.svg)
- TypeScript type checking for available symbols
npm install --save nuxt-svg-icon-sprite
export default defineNuxtConfig({
modules: ['nuxt-svg-icon-sprite'],
svgIconSprite: {
sprites: {
default: {
importPatterns: ['./assets/icons/**/*.svg'],
},
},
},
})
Place the icons in the folder defined in nuxt.config.ts
. By default, it's
./assets/icons
. The name of the SVG file determines the symbol name.
NOTE: Each symbol in a sprite must have a unique name!
So, if you have a file in ./assets/icons/user.svg
, the sprite will contain a
<symbol>
with the id user
.
You can now use the symbol with the provided component:
<SpriteSymbol name="user" />
This will render the following markup:
<svg>
<use xlink:href="/_nuxt/sprite.svg#user"></use>
</svg>
The symbol is referenced from the sprite via URL.
If you have a lot of icons, it might make sense to split them into separate sprites.
A typical example would be to have SVGs that appear on every page (navbar, logo, footer, etc.) in the "default" sprite and put page-specific SVGs in separate sprites.
To create an additional sprite, just define a new property on the sprites
config object:
export default defineNuxtConfig({
modules: ['nuxt-svg-icon-sprite'],
svgIconSprite: {
sprites: {
default: {
importPatterns: ['./assets/icons/**/*.svg'],
},
dashboard: {
importPatterns: ['./assets/icons-dashboard/**/*.svg'],
},
},
},
})
Assuming you have this file ~/assets/icons-dashboard/billing.svg
, you can
reference it like this:
<SpriteSymbol name="dashboard/billing" />
The symbol name is prefixed by the name of the sprite (e.g., the key used in the
sprites
config). The default
sprite is always unprefixed.
In addition to the name
prop, you can optionally pass the noWrapper
prop to
only render the <use>
tag:
<SpriteSymbol name="dashboard/billing" :no-wrapper="true" />
This will render the following markup:
<use xlink:href="/_nuxt/sprite-dashboard.svg#billing"></use>
This is useful if you want to render multiple symbols in one <svg>
tag.
You may also use the <SpriteSymbolInline />
component to render the SVG
content directly instead of rendering the <use>
tag. Note that this will load
the entire sprite, not just the symbol to be inlined.
<SpriteSymbolInline name="search" />
This will render the contents of the SVG file as-is, without any wrapper.
Get information about the generated sprites and their symbols during runtime.
Useful if you want to render a list of all symbols in a style guide:
<template>
<SpriteSymbol v-for="symbol in symbols" :key="symbol" :name="symbol" />
</template>
<script setup lang="ts">
const { symbols } = useSpriteData()
</script>
By default, the collected SVG symbols are used as-is, including any attributes
such as width
or height
. You can optionally provide processors to alter the
parsed SVG before it is added to the sprite.
The module exports a few processors you can use:
import { removeSizes, forceCurrentColor } from 'nuxt-svg-icon-sprite/processors'
export default defineNuxtConfig({
modules: ['nuxt-svg-icon-sprite'],
svgIconSprite: {
sprites: {
default: {
importPatterns: ['./assets/icons/**/*.svg'],
processSpriteSymbol: [removeSizes(), forceCurrentColor()],
},
},
},
})
This processor will remove width
and height
attributes on the <svg>
tag.
This processor will replace all fill
and stroke
attribute values with
currentColor
. If you still want to keep some stroke or fill attributes, you
can add a data-keep-color
attribute on them - those will then be skipped.
Prefixes all IDs and classes in a SVG, including <style>
selectors. Note that
it does not prefix other selectors (e.g. path {}
) - these will be shared for
all symbols in the sprite!
Removes the given tags. For example, to remove all <title>
tags from the SVG:
import { removeTags } from 'nuxt-svg-icon-sprite/processors'
export default defineNuxtConfig({
modules: ['nuxt-svg-icon-sprite'],
svgIconSprite: {
sprites: {
default: {
importPatterns: ['./assets/icons/**/*.svg'],
processSpriteSymbol: [removeTags({ tags: ['title'] })],
},
},
},
})
You can also provide your own processors as inline methods:
import { removeSizes, forceCurrentColor } from 'nuxt-svg-icon-sprite/processors'
export default defineNuxtConfig({
modules: ['nuxt-svg-icon-sprite'],
svgIconSprite: {
sprites: {
default: {
importPatterns: ['./assets/icons/**/*.svg'],
processSpriteSymbol: [
(svg) => {
// Removes all <title> tags.
const titles = svg.querySelectorAll('title')
titles.forEach((title) => title.remove())
},
],
},
},
},
})
import type { HTMLElement } from 'node-html-parser'
export default defineNuxtConfig({
modules: ['nuxt-svg-icon-sprite'],
svgIconSprite: {
sprites: {
default: {
importPatterns: ['./assets/icons/**/*.svg'],
// Directly provide symbol SVG by path.
// These are added after the auto imports defined in
// `importPatterns`.
symbolFiles: {
email: '~/node_modules/some_package/assets/icons/email.svg',
},
processSpriteSymbol(svg: HTMLElement) {
// Executed for each sprite symbol.
// Remove width and height attributes from the SVG.
svg.removeAttribute('width')
svg.removeAttribute('height')
// Use 'currentColor' for all fills and strokes.
const elements = svg.querySelectorAll('*')
const attributes = ['stroke', 'fill']
elements.forEach((el) => {
attributes.forEach((name) => {
const value = el.getAttribute(name)
if (value) {
el.setAttribute(name, 'currentColor')
}
})
})
},
processSprite(sprite, ctx) {
// Executed for each sprite right before it's saved.
// Run SVGO or whatever you like.
// Markup contains:
// <svg>
// <symbol id="user">...</symbol>
// <symbol id="foobar">...</symbol>
// </svg>
// You can directly manipulate the `sprite` object.
},
},
},
},
})
The options are the same for each key in sprites
.