Build an SVG Sprite for Vite, React & Vue

By the Axialis Engineering team ·

Build an SVG Sprite for Vite, React & Vue

Shipping dozens of standalone SVG files means dozens of requests, duplicated markup, and icons that drift out of sync. A symbol sprite solves this: one cached file holds every icon, and each <svg><use> reference pulls a symbol from it by id.

This guide takes clean per-icon SVGs exported from Axialis IconVectors and turns them into a sprite two ways — an automatic build via the vite-plugin-svg-icons plugin (Route A), or a static public/sprite.svg from the svg-sprite CLI (Route B). You then reference icons with <use> and handle caching and same-origin gotchas.

Export clean per-icon SVGs from IconVectors

  1. Open or create your icons:
    • File -> Open... (Ctrl+O) or New Icon (Ctrl+N).
    • Prefer currentColor paints and a tidy viewBox (e.g., 0 0 24 24) so icons inherit text color and scale cleanly.
    • File -> Export -> Export Minified (Shift+Ctrl+M) for lean, SVGO-friendly output.
    A single 24x24 SVG icon open in the IconVectors editor, ready to export as a minified per-icon file
    Keep one icon per file in src/icons/, named consistently (e.g., check.svg, alert.svg) — both sprite tools derive symbol ids from these filenames.

Route A — Vite plugin (auto sprite for React/Vue)

  1. Install the plugin:
    npm i -D vite-plugin-svg-icons
    # or: pnpm add -D vite-plugin-svg-icons
    # or:  yarn add -D vite-plugin-svg-icons

    The plugin scans src/icons, builds a symbol sprite, and injects it into the document at runtime — with hot-module reload as you add icons. You configure SVGO and a stable symbolId pattern in the next step.

  2. Configure vite.config.ts
    import { defineConfig } from 'vite'
    import vue from '@vitejs/plugin-vue' // or: import react from '@vitejs/plugin-react'
    import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
    import path from 'path'
    
    export default defineConfig({
      plugins: [
        // vue(), or react(),
        createSvgIconsPlugin({
          iconDirs: [path.resolve(process.cwd(), 'src/icons')],
          symbolId: 'icon-[dir]-[name]',
          svgoOptions: {
            plugins: [
              { name: 'preset-default', params: { overrides: { removeViewBox: false } } },
              'removeDimensions',
              'prefixIds' // prevent ID collisions across icons
            ]
          },
          inject: 'body-last'
        })
      ]
    })
  3. Register sprite & use icons
    // main.ts or main.tsx (React/Vue entry)
    import 'virtual:svg-icons-register'
    
    // React component
    export function Button() {
      return (
        <button className="inline-flex items-center gap-2 text-blue-600">
          <svg className="w-5 h-5" aria-hidden="true">
            <use href="#icon-check" /> {/* symbolId = icon-[dir]-[name] */} 
          </svg>
          Save
        </button>
      )
    }
    <!-- Vue SFC snippet -->
    <template>
      <button class="inline-flex items-center gap-2 text-emerald-600">
        <svg class="w-5 h-5" aria-hidden="true"><use href="#icon-check" /></svg>
        Save
      </button>
    </template>

    Note: use href on <use>. The older xlink:href is deprecated; add it only as a fallback for legacy engines.

Route B — NPM CLI (build a static public/sprite.svg)

  1. Install the CLI:
    npm i -D svg-sprite

    svg-sprite can emit several sprite modes (symbol, stack, view, css); pick symbol for the <use> approach used here.

  2. Add a script that builds one sprite from all icons:
    {
      "scripts": {
        "build:sprite": "svg-sprite -s --symbol-dest public --symbol-sprite sprite.svg src/icons/*.svg"
      }
    }

    This compiles every SVG in src/icons into a single public/sprite.svg. Each file becomes a <symbol> whose id matches the filename. Adjust the source glob and dest paths to fit your project.

  3. Reference icons in markup:
    <!-- External sprite placed under /public -->
    <svg class="icon w-5 h-5" aria-hidden="true">
      <use href="/sprite.svg#check" /> <!-- or: href="/sprite.svg#icons-check" if your tool prefixes -->
    </svg>
    • Caching: serve with far-future cache headers, then bust it with a content hash or query (e.g., /sprite.abc123.svg or /sprite.svg?v=abc123) when icons change.
    • Same-origin: referencing an external sprite via <use> requires same-origin (or correct CORS headers), so host sprite.svg on your own domain.

When to pick which route

IconVectors export tips

Troubleshooting

Either route ends in the same place: one cached sprite, clean <use> references, and icons that theme with currentColor. Start with well-formed source SVGs from IconVectors — consistent viewBox, minified, prefixed ids — and the build step stays trivial whichever tool you pick.

Related guides

Start Making SVG Icons Today with IconVectors

Download the fully-functional 30‑Day Free Trial and unlock your icon design workflow.

Version 1.70 for Windows and macOS