-
|
I've been tinkering with using SVGs in Vite+Vue3 environment, writing in TypeScript, for a few days, and I'm confused about a specific case.
Result: SVG does not render properly on to Why this specific behaviour? I suspect that Vite should already handle such a common case natively, I am probably not aware of it since I'm new to Vite and Vue. Can you explain why my approach doesn't work? What should be changed to fix it? |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 2 replies
-
|
I think the main issue is that For a sprite placed at <script setup lang="ts">
const sprite = `${import.meta.env.BASE_URL}svg_sprite.svg`
</script>
<template>
<svg aria-hidden="true">
<use :href="`${sprite}#logo`" />
</svg>
</template>If your app is always deployed at the domain root, Why your current approach behaves oddly:
So the simplest native Vite setup is: keep the ready-made sprite in |
Beta Was this translation helpful? Give feedback.
-
|
Files in For SVG sprites in <template>
<svg>
<use href="/svg_sprite.svg#icon-name" />
</svg>
</template>No import needed. Vite serves everything in If you want to import the sprite (for hashing, tree-shaking, etc.), move it to <script setup lang="ts">
import spriteUrl from '@/assets/svg_sprite.svg?url';
</script>
<template>
<svg>
<use :href="`${spriteUrl}#icon-name`" />
</svg>
</template>TL;DR:
Don't mix the two. The |
Beta Was this translation helpful? Give feedback.
-
|
The issue is that Since your sprite is in <template>
<svg>
<use href="/svg_sprite.svg#logo"></use>
</svg>
</template>No import needed. The The problem with your approach: importing from If you want the sprite in <script setup lang="ts">
import spriteUrl from '@/assets/svg_sprite.svg?url'
</script>
<template>
<svg>
<use :href="`${spriteUrl}#logo`"></use>
</svg>
</template>And in build: {
assetsInlineLimit: 0, // for SVGs only, use a custom plugin instead
}Or better — use a targeted approach with a plugin that only disables inlining for your sprite: // vite.config.ts
export default defineConfig({
plugins: [{
name: 'no-inline-sprite',
enforce: 'pre',
load(id) {
if (id.includes('svg_sprite.svg')) {
return null; // skip inlining, let it be a file
}
}
}]
})But honestly, keeping the sprite in |
Beta Was this translation helpful? Give feedback.
The issue is that
?urldoesn't actually prevent inlining when the file is under theassetsInlineLimitthreshold. In dev mode, Vite serves everything as modules and the?urlsuffix gives you a URL, but it's still processed through Vite's asset pipeline which can transform it.Since your sprite is in
/public, you shouldn't import it at all — files inpublic/are served as-is and available at the root URL. Just reference it directly:No import needed. The
/public/svg_sprite.svgfile is served at/svg_sprite.svgby both the dev server and the production build. This avoids the entire inlining/bundling pipeline.T…