Assets with a dynamic URL are ignored
See original GitHub issueIs your feature request related to a problem? Please describe.
When something like <img src=example.png>
is used in a Vue template, vite build
handles it by copying the PNG file into the dist
directory with a hash in the filename etc. However this doesn’t happen when the image filename is dynamic. For example:
<ul>
<li v-for="item in items">
<img v-bind:src="`icons/${item.slug}.png`" />
{{ item.name }}
</li>
</ul>
The src
attribute in the browser’s DOM are exactly the result of template interpolation, which works out with Vite’s own development server but not in “production” since image files are missing.
Describe the solution you’d like
I sort of understand why this doesn’t Just Work, but it’d be nice if it did. Alternatively, is there some other ways to tell Vite about which images exist? The value of item.slug
is always in some finite set, although there are more of them that I’d rather hard-code in a template. Or, am I doing something very wrong and shouldn’t use reactive data for this? I’m very new to Vue.
Describe alternatives you’ve considered
Moving these images to the public
directory would probably work, but Vite’s README describes this as an escape hatch that is best avoided.
Issue Analytics
- State:
- Created 3 years ago
- Reactions:13
- Comments:24
Top GitHub Comments
As mentioned in https://github.com/vitejs/vite/issues/1265#issuecomment-757450141, I tried using
glob
likeconst images = import.meta.globEager("/src/images/*.png");
. It wasn’t working at first, then I realized that you need to use.default
likeimages["/src/images/image.png"].default
.Just FYI for any one else trying to use globs with static assets.
Based on @amir20 I ended up doing something like this:
Then in any file:
This way you can keep all your assets in one place and avoid magic strings. It’s a little bit more work to add each asset in the composable return, but in the long run it’s quite nice,