0

I am trying to dynamically load a VueJs image so that I can change it later but I keep getting a "404 not found" error.

Here is the img tag

<img class="image" :src="imageSrc" alt="image">

and the js code.

export default {
  data () {
    return {
      imageSrc: '@/assets/gallery/images/20211005_0044.jpg'
    }
}

If I put that same path directly into the img like this, it does work so the image does exist. I have also tried using ref and changing the src like that and then at first the image will load (with the path directly in the src) but as soon as I tried to change it I would get a 404 not found error back.

Note: I have seen this question Vuejs image src dynamic load doesn't work but that did not help either.

Thanks.

Tolbxela
  • 4,767
  • 3
  • 21
  • 42
Elias Mulderij
  • 29
  • 1
  • 1
  • 6
  • Could you explain more about why the linked question's answer didn't work for you? What gets interpolated into the image's src attribute? Is it the raw string (beginning in `@` ), or a valid URL that just happens to point to the wrong location? In another related question https://stackoverflow.com/a/75881654/2977638 I found that sometimes `require` ends up creating a base64-encoded string, which could also be a problem for this particular use case. – RNanoware Apr 12 '23 at 15:43
  • I use v-bind:src="imageSrc" in my code and imageSrc = "imageSrc: '@/assets/gallery/images/image.jpg'", that does not work but when I put that same path (imageSrc: '@/assets/gallery/images/image.jpg') into the src (not using v-bind) it does work so the path is correct. I tried the solution given in the linked question but it did not help and I got the same error message. as of right now I am not using 'require' – Elias Mulderij Apr 12 '23 at 16:20

1 Answers1

2

Note: this entire answer uses require to solve the problem. I know of no workarounds that avoid explicit import utilities.


There are a couple of Vue/Webpack quirks at play here.

First, Webpack only knows how to convert a certain limited set of import path specifications into appropriate URLs in the final build. Using a data variable as the value of a :src prop is not a supported syntax: Webpack just sees that as a generic variable and will not transform it.

As mentioned in the question linked above, a first step to resolving the issue is using the require() syntax like so:

<img class="image" :src="imageSrc" alt="image">
export default {
  data () {
    return {
      imageSrc: require('@/assets/gallery/images/20211005_0044.jpg')
    }
  }
}

However, there is an additional quirk when the path in require needs to be dynamic. According to this answer, Webpack cannot import the file if its name is completely given as a variable. In other words, require(this.imageSrc) (where imageSrc is a string variable) will not work.

A workaround is to only include a subdirectory (or filename) in a variable, and use a static prefix in a string, like so:

<img class="image" :src="imageSrc" alt="image">
export default {
  data () {
    return {
      imageName: '20211005_0044.jpg'
    }
  },
  computed: {
    imageSrc () {
      return require(`@/assets/gallery/images/${this.imageName}`);
    }
  }
}
RNanoware
  • 551
  • 6
  • 16