nuxt-svg-icon-sprite
TypeScript icon, indicating that this package has built-in type declarations

2.0.0 • Public • Published

Nuxt SVG Icon Sprite

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

Install

npm install --save nuxt-svg-icon-sprite
export default defineNuxtConfig({
  modules: ['nuxt-svg-icon-sprite'],

  svgIconSprite: {
    sprites: {
      default: {
        importPatterns: ['./assets/icons/**/*.svg'],
      },
    },
  },
})

Usage

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.

Multiple Sprites

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.

<SpriteSymbol> component

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.

useSpriteData() composable

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>

Processing SVG Files

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()],
      },
    },
  },
})

removeSizes()

This processor will remove width and height attributes on the <svg> tag.

forceCurrentColor()

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.

cssPrefix() (Experimental)

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!

removeTags()

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'] })],
      },
    },
  },
})

Custom Processors

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())
          },
        ],
      },
    },
  },
})

Full Module Options

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.

Readme

Keywords

none

Package Sidebar

Install

npm i nuxt-svg-icon-sprite

Weekly Downloads

710

Version

2.0.0

License

MIT

Unpacked Size

48.7 kB

Total Files

24

Last publish

Collaborators

  • dulnan