Why Does Vue 3 Only Render First SVG in Sprite?

Viewed 552

I have a Vue 3.1.1 project and I'm seeing a bizarre issue. If I put an SVG file in my template that references a sprite, only the first instance of it appears.

Here's my template code:

<template>
<div>
  <svg>
    <use href="@/assets/images/icons-master.svg#project"></use>
  </svg>
  <svg>
    <use href="@/assets/images/icons-master.svg#project"></use>
  </svg>
</div>
</template>

Here's how it renders in the DOM (tested in Chrome, Firefox, and Safari):

enter image description here

See how it removes the #project from the file path on the second SVG?

If I try a different filename, I can see the first instance of where the file is used, and subsequent SVGs have the #id removed and don't show up.

My SVG file is structured as follows.

<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
  <symbol id="project" viewbox="0 0 16 17">
    <g ...>
      <path ...>
      </path>
    </g>
  </symbol>
</svg>

This used to work fine in Vue 2.x. Is this incorrect SVG syntax or a bug in Vue?

1 Answers

This might be a bug with Vite, but it looks like a workaround is to not use the @ path component from vite.config.js:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, '/src'),
    },
  }
})

So the workaround is to change the SVG path to this:

src/assets/images/icons-master.svg#project

Where src replaces @.

Related