mikeym
mikeym

Reputation: 6311

How to use dynamic images in Nuxt?

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.

Upvotes: 4

Views: 19007

Answers (6)

Cristian Scheel
Cristian Scheel

Reputation: 878

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

Upvotes: 0

Kamil Kaczmarczyk
Kamil Kaczmarczyk

Reputation: 11

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.

Upvotes: 1

Arion Paul
Arion Paul

Reputation: 43

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" />

Upvotes: 1

kissu
kissu

Reputation: 46594

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.

Upvotes: 2

Michael Stachura
Michael Stachura

Reputation: 1370

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 :)

Upvotes: 0

Liviu
Liviu

Reputation: 319

in Nuxt v3, you can use it like so

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

<template>
  <img :src="img1" />
</template>

Upvotes: 8

Related Questions