framework
framework copied to clipboard
Image assets imported relatively in components are not processed properly
Environment
- Operating System:
Linux - Node Version:
v14.18.1 - Nuxt Version:
3.0.0-27386759.b449d0b - Package Manager:
[email protected] - Bundler:
Vite - User Config:
- - Runtime Modules:
- - Build Modules:
-
Reproduction
https://codesandbox.io/s/prod-cdn-2g32p
Describe the bug
I am trying to put the image assets in the components path (next to the .vue component files) and try to use them by a relative path like <img src="./play.svg" />, the assets are not loaded properly in nuxi build, though they work well in nuxi dev.
Additional context
No response
Logs
No response
Try putting this in your nuxt.config:
//...
vite: {
build: { assetsInlineLimit: 0 },
},
Try putting this in your nuxt.config:
//... vite: { build: { assetsInlineLimit: 0 }, },
I updated the sandbox and added this config. But it still doesn't work.
The same goes for images that are inside the assets folder. I have the structure ./assets/img/test-img.jpg and try to use it inside a picture tag with srcset="~/assets/img/test-img.jpg" which doesn't work when running npm run dev.
Using srcset="assets/img/test-img.jpg" or srcset="/assets/img/test-img.jpg" works.
I created a sample project to check and reproduce this issue. I am using NodeJs version 14.16.1.
Sample Project: https://github.com/Der-Alex/image-asset-example
Hmm, I just checked this out in my own project. Yes, this is a troubling issue. Don't know why this is marked as a minor bug if it doesn't have a workaround.
Edit: made a workaround. Not good if you want component-level interactivity, though. You might have to use render functions at that point.
Component.vue
<template>
...
<slot name="img"/>
...
</template>
Page.vue
<template>
...
<component>
<template #img>
<img src="/* put asset here */" /* ... */ />
</template>
</component>
// all other functionality should be directly be put in the page itself
// styling should be in the page stylesheet, I tried putting scoped CSS for the image
// in the component, but that's not working
...
</template>
@Der-Alex have you tried using a larger image or adding this config?
vite: {
build: { assetsInlineLimit: 0 },
},
Because when I did in your example none of the methods worked with npm run start
@baronkoko See: https://github.com/nuxt/framework/issues/2939#issuecomment-1022825138
@StevenJPx2 thank you for the quick response.
I set this config and tried to import assets in two ways /assets/... and assets/....
Both of these methods work great with npm run dev. But none works with npm run build npm run start.
Сan you take a look, please? Maybe I made a mistake somewhere, but in another project, I have the same thing.
Nuxt CLI v3.0.0-27415326.3c563fa
Reproduction: https://github.com/baronkoko/nuxt3-assets
As far as I can see in my case this is a problem with loading assets via the srcset attribute. Assets are loaded fine via the src attribute with @/ alias on both dev and prod versions.
Can anyone help with the assets loading via the srset attribute, please?
@baronkoko As it stands, you can't use srcset or add an image path into a component, because it won't render in build. For the component fix, I have given a workaround, srcset would probably need you to do a JS workaround by detecting screen-size and changing the image that way.
stands
<img> src attribute works great, it doesn't need a workaround. Or maybe I misunderstood you in this regard.
The only problem with srcset. It does not work with npm run build npm run start. The path is generated, even with a hash, but there are no assets in the _nuxt folder.

@baronkoko Yeah, I mentioned how to work around srcset not working by using src alone.
@StevenJPx2 got it, thank you. Will this srset problem be fixed or do you not have such information?
No idea. I hope it gets fixed soon. @danielroe?
When is this getting resolved? This might have to do with Vue-loader, maybe?
Okay, so this is a Vite issue. I had to move away from using Nuxt 3 to Vitesse to see what the incompatibilities are and this props up there as well.
This solved the issue for me.
Essentially, you have to import the image as a module of sorts, line this:
<script setup>
import imgSrcWithAlias from '@/assets/icon-1.svg'
</script>
<template>
<component-a :img-src="imgSrcWithAlias" />
</template>
And this works in Vitesse. @baronkoko I don't know if this fixes your srcset issue but I think this fixes @doomspec issue.
@StevenJPx2 this will mark all images as prefetch to read them on page load.
don't do this if you are using responsive images for various resolutions. Then they will be all loaded at the beginning.
@hoomb I wasn't aware of that. Either way, this looks to be a Vite issue, right?
@StevenJPx2 yes. It is a Issue with Vite
This works for me:
<img src="@/assets/images/myimage.jpg" alt="my image">
And regarding to the Problem with responsive images and srcset, this is the solution which I'm using till there comes a fix from Vite
<style lang="scss" scoped>
@mixin bg-image($img) {
background: url(~/assets/images/#{$img}_sm.jpg) no-repeat center center;
background-size: cover;
@media (min-width: 720px) {
background: url(~/assets/images/#{$img}_md.jpg) no-repeat center center;
background-size: cover;
}
@media (min-width: 1024px) {
background: url(~/assets/images/#{$img}_lg.jpg) no-repeat center center;
background-size: cover;
}
@media (min-width: 1920px) {
background: url(~/assets/images/#{$img}_xl.jpg) no-repeat center center;
background-size: cover;
}
}
.slide-image {
width: 100%;
height: 100%;
&.slide-0 {
@include bg-image(image1);
}
&.slide-1 {
@include bg-image(image2);
}
}
</style>
@hoomb Problem is not with adding the image source directly to an image element. The problem is with passing the image path as a prop to a component which then loads it into an image element. Vite seems to not resolve paths which do not load directly into an img[src].
@StevenJPx2 @hoomb Thank you both. I tried srcset in Vite Vue and there it works fine with the relative path.
I updated my example of using srcset in the Nuxt 3 (https://github.com/baronkoko/nuxt3-assets) using the relative path, but unfortunately, it also only works with npm run dev, but not with npm run build npm run start.
As I noticed, with npm run build npm run start Nuxt 3 does not create these files in the .output/public/_nuxt folder, although the paths are correct and a hash is added.

@baronkoko It will work with bare Vite Vue because it is processing the page as an SPA. Everything rendered will be on the client side. So, Vitesse uses SSG which prerender items on the page and Nuxt uses both SSR and SSG. This is what causes the build issues.
@StevenJPx2 so, since we know what the problem is, we only have to wait until it is fixed, right?
I looked more into the problem.
I went into my node_modules and found this code and added there srcset and it works fine. 🤔
ps: I've used patch-package to patch the lib
I looked more into the problem.
Can you check for any components not loading any image sources in the build for SSR AND SSG?
Any updates on this one?
Same,it seems these image assets are not packed by nuxt. All image tags are still using the relative path.
There is a possible way via importing the image, and then bind the img src prop with imported image.
There is a possible way via importing the image, and then bind the img src prop with imported image.
Yes, we did discuss that above. But @danielroe, is there any movement on this?
I can't reproduce this now on RC8 - I believe the Vite 2 -> 3 upgrade has resolved this issue. If not, please provide a reproduction and I'll look into it.