5

I am trying to display images from an assets folder in a Nuxt but it won't work even if the src value in the HTML is correct.

Here is an excerpt of the code.

<div v-for="(item, index) in items" :key="index">
  <div class="item-img">
   <img :src="`../assets/imgs/${item.img}`"/>
  </div>
</div>

The above path is correct as the component is inside a pages folder at the same root level as the assets folder.

I have image filenames in an array like so:

data() {
  return {
    images: ['image0.jpg', 'image1.jpg'],
  ...
}

There is an async function that is making an API call to fetch some items. When the API is finished a random image is added to each item.

async getMovies() {
  const data = axios.get `api_call_here`)
  const result = await data
  result.data.results.forEach((item) => {
    let randomImg = 
    this.images[Math.floor(Math.random() * 
    this.images.length)]
    item.img = randomImg
    this.items.push(item)
  })
},

I am sure the path to the images is correct and that they exist in the specified folder. I also know the path works because I can display any single image from the same assets folder inside another component at the same level.

I think I have tried every combination for the interpolation inside the src attribute and nothing has worked.

Lastly, I can see the correct path in the elements themselves when I inspect them in the developer console. What is even more baffling is the images seem to be taking up the appropriate space on the page but they are empty (blank space).

I have run out of ideas. If anyone can help me figure out what is going wrong I'd be very grateful.

7
  • have you defined items in data ? Commented Apr 19, 2022 at 4:13
  • @Saeed yes, items is defined on data also. I forgot to mention that the other values of each item in the v-for display perfectly fine, so there is no problem there. It is simply that the img element is not displaying the images despite the fact that the correct paths are in the HTML. Commented Apr 19, 2022 at 4:18
  • taking up the appropriate space, did you check width and height of images? any overflow hidden style or something like that? Commented Apr 19, 2022 at 4:24
  • @Saeed there is an overflow hidden on the div wrapping the img tag. The height and width on the img tag itself are 100%. I just tried pasting in a url using the dev console and it immediately showed on the page, so I think the CSS is fine. Commented Apr 19, 2022 at 4:39
  • Does this answer your question? Vue.js dynamic images not working Commented Apr 19, 2022 at 7:22

6 Answers 6

8

in Nuxt v3, you can use it like so

<script setup>
import img1 from `~/path/to/img1`
</script>

<template>
  <img :src="img1" />
</template>
Sign up to request clarification or add additional context in comments.

3 Comments

How can you get this to work with dynamic images in Nuxt 3?
Just import all images that you may need dynamically. you may place them in an object or array. If you have a ton of images and is not doable for you, most probably must move your images on a CDN and get full URLs from there. Another option would be to place your images in the public/ folder. I would also like to know if there's a better way to dynamically import assets in Nuxt 3. Will come up with an update if I find out.
I have the same issue on asset and used a public folder for now but it is the recommended way?
2

For Vue3/Nuxt3

https://www.lichter.io/articles/nuxt3-vue3-dynamic-images/


For Nuxt2

Try to use it this way

<img :src="require(`../assets/imgs/${item.img}`)" />

As shown in the Nuxt documentation regarding the images.

9 Comments

Please note that this solution does not work in Nuxt 3, it will only work in Nuxt 2
@Maurice rectification, this only works with Webpack, not with Vite. Nuxt3 can be used with Webpack5.
good callout. I guess by default, the Nuxt3 project generator configures new projects with Vite, which is why this option didn't work for me. Also worth noting is that there is an issue open on GH around better handling for this situation: github.com/nuxt/framework/issues/7121
I have tried this but not working on nuxt 3 version
@OlaboyeDavidTobi nothing that is not already in my answer above. Using public has quite some drawbacks tho (as written above).
|
2

I think i just found an easy solution for Nuxt 3. I used <NuxtImg> for dynamic images. It worked both during development and in my production build.

Note that <NuxtImg> by default looks up files in public directory, in my case directory looked like this public > images

<NuxtImg :src="'images/' + yourImage" />

Comments

1

In Nuxt 3 Vue composition API You can put images in public directory or assets directory.

If you will use images from public directory it will work, but Webpack will not optimize them, so it's not a professional solution.

If you want use images from assets directory dynamically, first You need to get a new "webpack" path with new changed filename. You can do it in code by import image like this:

import img_1 from '~/assets/fences_1.png';
import img_2 from '~/assets/fences_1.png';

Then you can optionally have an object which can use this data for looping.

{
      name: "name",
      photo_url: img_1,
      link_url: "/index",
    },

as a path use imported img_1 it will change automatically.

Now you can use it in HTML like this:

:style="{ 'background-image': 'url(' + item.photo_url + ')' }"

It works in development and production.

Comments

1

in Nuxt, the best way to do is

<img :src="`/_nuxt/assets/${image}`"/>

This worked for me and solve my problems

Also another more proper way in nuxt is to put your image in public folder, for example un

public/img/1.png

then you can reference

<img class="img-fluid" src="@/assets/img/1.png"/> 

Nuxt will take by default resources from public and you can reference with @/assets

2 Comments

This won't work once you deploy your application
another way and more proper in nuxt is to put your image in public folder, for example un public/img/1.png, then <img class="img-fluid" src="@/assets/img/1.png"/> Nuxt will take by default resources from public and you can reference with @/assets
0

Worinkg with Nuxt 3 and import img1 from ~/path/to/img1 works fine but I've had an error while working with typescript. I think in Nuxt 2 dynamic :src attributes was working better :).

Anyway if you like to play with typescript and don't want to have an errors see my approach below. $slugify is just an extra plugin I needed to convert attribute to right image name.

Stack:

  • Nuxt 3 with typescript (docs)
  • Tailwind

plugins/slugify.ts

export default defineNuxtPlugin(() => {
  return {
    provide: {
      slugify: (text: string) => {       
        return `${
          text
            .toLocaleLowerCase()
            .trim()
            .replace(/[^\w\s-]/g, '')
            .replace(/[\s_-]+/g, '-')
            .replace(/^-+|-+$/g, '')
          }`
      }
    }
  }
})
// "Any String" will be converted to "any-string"

components/ImageComponent.vue

<script setup lang="ts">
const props = defineProps({
    imageSrc: {
      type: String,
      required: true,
    }
})
</script>

<template>
  <div
    :class="`bg-[url('${props.imageSrc)}')]`"
  >
  <div>
</template>

Usage

<template>
  <div>
    <h1>My awesome image.png</h1>
    <ImageComponent
      class="w-16 h-16 bg-contain"
     :image-src="`${$slugify('My awesome image.png')}`"
    />
  </div>
</template?

my-awesome-image.png must be placed in public folder


Another way - the easiest one!!!

You can also use Nuxt Image where you can pass image :src in a dynamic way :)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.