SooJungChae
SooJungChae

Reputation: 229

How to pass dynamic image url in nuxt project

I want to pass image url to child component but image is not showing.

I tried v-attr, :attr, :src properties.

pages/index.vue

<ThumbNail img-url="assets/img/igsim_intro.png"/>

components/Thumbnail.vue

<!-- Failed to resolve directive: attr -->
<img v-attr="imgUrl" /> 

<!-- 404 Not found: http://localhost:3000/assets/img/pds_main.png -->
<img :src="imgUrl" />

<img :attr="{src: imgUrl}" /> 
<script>
export default {
  name: "ThumbNail",
  props: {
    imgUrl: {
      type: String,
      default: ''
    }
  }
}
</script>

I expect Thumbnail.vue show images as passed url.

Upvotes: 14

Views: 36908

Answers (13)

Timar Ivo Batis
Timar Ivo Batis

Reputation: 1996

For Nuxt 3 it's best to put the image in the public Folder and use like so.

The image is in /public/img/logo.png

<img :src="'/img/logo.png'" />

https://nuxt.com/docs/getting-started/assets

Upvotes: 0

Find solution here https://stackoverflow.com/a/75858765

  1. Create method

    const getImageUrl = (imagename) => { const imageUrl = new URL(/assets/img/${imagename}, import.meta.url).href; return imageUrl; };

  2. <NuxtImg :src="getImageUrl(imgSrc)" :alt="imgAlt" />

Upvotes: 0

Marek Miś
Marek Miś

Reputation: 291

If possible in your situation, you can move the image to public folder where it won't be compiled but will be available as is, on the path you specify. If you need Nuxt to process your image then answer given by @Aditya Kresna Permana is correct.

Upvotes: 1

suchrile
suchrile

Reputation: 21

This will work for Nuxt 3 with Vite

<template>
  <img :src="getImageUrl()" :alt="alt">
</template>

<script setup lang="ts">
const props = defineProps({
  img: { type: String, default: 'placeholder.png' },
  alt: { type: String, default: 'Image' }
})

const getImageUrl = () => {
  return new URL(`/assets/images/${props.img}`, import.meta.url)
}
</script>

Upvotes: 2

according to Nuxt.JS document assets directory structure:

Inside your vue templates, if you need to link to your assets directory use ~/assets/your_image.png with a slash before assets. Nuxt.JS directory structure

<ThumbNail img-url="~/assets/img/igsim_intro.png" />

Upvotes: 0

Sasha Kos
Sasha Kos

Reputation: 2608

According to https://nuxtjs.org/docs/directory-structure/assets/

<img :src="require(`~/assets/img/${image}.jpg`)" />

Upvotes: 2

Ziyad Adel
Ziyad Adel

Reputation: 1

when you have different ports LIKE http:127.0.0.1:8000 (LARAVEL)

data: () =>({ img: process.env.baseUrl, }),

<img :src="img + product.image" :key="product.id">

Upvotes: 0

minlare
minlare

Reputation: 2654

I had a similar scenario when using a <video> component.

I needed to utilize nuxt's assets directory but could not pass ~/assets/video.mp4 down to the child as it was not getting compiled into /_nuxt/assets/video.mp4

To get around the issue I used a <slot> as seen below.
https://v2.vuejs.org/v2/guide/components-slots.html

Then I could either pass a String as the src or a generated asset path.

Following this example you could probably use a <Picture> element to achieve the same result with images.

Child Component

<template>
  <video>
    <slot>
      <source :src="src" />
    </slot>
  </video>
</template>

<script>
export default {
  name: 'VideoComponent',
  props: {
    src: String
  }
}
</script>

Parent Component

<template>
  <VideoComponent src="video-1.mp4" />

  <VideoComponent>
    <source src="~/assets/video.mp4" />
  </VideoComponent>
</template>

<script>
export default {
  props: {
    src: String
  }
}
</script>

Upvotes: 0

Aditya Kresna Permana
Aditya Kresna Permana

Reputation: 12099

As the src properties will be replaced by Webpack, you could do require function like this

ChildComponentExample.vue

<templae>
  <div>
    <img :src="imageUrl">
  </div>
</template>

<script>
export default {
  props: {
    imageUrl: {
      type: String,
      default: ''
    }
  }
}
</script>

ParentComponent.vue

<template>
  <ChildComponentExample :image-url="require('~/assets/myimage.png')" />
</template>

Upvotes: 29

Sabee
Sabee

Reputation: 1811

It is prety simple see the examle on codesandbox. And be sure you use the right path to the image.

parent

<template>
  <Logo :width="350" :image-src="image"/>
<template>
  ....

<script>
import Logo from '~/components/Logo.vue'
  
export default {
  components: {
    Logo
  },
  data() {
    return{
      image:'http://4.bp.blogspot.com/-jjDh65rKHak/Vipmdm4eYtI/AAAAAAAAABU/j9iH8nRP3Ms/s1600/bist%2Bimege.jpg'
    }
  }
}
</script>

child

<template>
  <div>
    <svg :width="width" :height="height" viewBox="0 0 452 342" xmlns="http://www.w3.org/2000/svg">
      <g fill="none" fill-rule="evenodd">
        <path
          d="M139 330l-1-2c-2-4-2-8-1-13H29L189 31l67 121 22-16-67-121c-1-2-9-14-22-14-6 0-15 2-22 15L5 303c-1 3-8 16-2 27 4 6 10 12 24 12h136c-14 0-21-6-24-12z"
          fill="#00C58E"
        />
        <path
          d="M447 304L317 70c-2-2-9-15-22-15-6 0-15 3-22 15l-17 28v54l39-67 129 230h-49a23 23 0 0 1-2 14l-1 1c-6 11-21 12-23 12h76c3 0 17-1 24-12 3-5 5-14-2-26z"
          fill="#108775"
        />
        <path
          d="M376 330v-1l1-2c1-4 2-8 1-12l-4-12-102-178-15-27h-1l-15 27-102 178-4 12a24 24 0 0 0 2 15c4 6 10 12 24 12h190c3 0 18-1 25-12zM256 152l93 163H163l93-163z"
          fill="#2F495E"
          fill-rule="nonzero"
        />
      </g>
    </svg>

    <img :src="imageSrc" />
  </div>
</template>

<script>
export default {
  props: {
    width: {
      type: Number,
      default: 452,
    },
    height: {
      type: Number,
      default: 342,
    },
    imageSrc: {
      type: String,
      required: true,
    },
  },
}
</script>

Upvotes: 0

Saurabh Chandra Rai
Saurabh Chandra Rai

Reputation: 65

This is how I will do. I have faced a similar problem and got the solution is that. You have to keep your images in the static folder, not in the assets folder and then just s do this.

In your component thumbnail.vue file.

<template>
    <div class="thumbnail-image">
      <img :src="thumbnail">
    </div>
</template>

<script>
  export default {
  props: {
    thumbnail: String
    }
  }
</script>

Now in your Pages.

Import the component and do this.

<template>
  <thumbnail thumbnail="/images.jpg" />
</template>

<script>
import Thumbnail from '~/components/thumbnail'

export default {
  components: {
    Thumbnail
  }
}
</script>

the path after / automatically goes to the static folder. Remember to put your assets in static folder otherwise, you will get a white blank div.

well, its good to have assets in assets folder but in this situation, you gotta keep those in the static folder. Hope this will solve your problem

Upvotes: 0

l2D
l2D

Reputation: 334

From this answer by Aditya Kresna Permana

For me, It's not working correctly because :image-url in ParentComponent.vue not the same as props in ChildComponentExample.vue

:image-url="require('~/assets/myimage.png')" change :image-url to :imageUrl (same as in props in ChildComponentExample.vue )

Result: :imageUrl="require('~/assets/myimage.png')"

Example ParentComponent.vue:

<template>
  <div v-for="item in items" :key="item.id>
    <ChildComponent 
      :imageURL="require(`~/assets/${item.imgURL}`)" 
      :title="item.title"
      :descriptions="item.descriptions"
    />
  </div>
</template>

<script>
import ChildComponent from '~/components/ChildComponentExample.vue'

export default {
components:{
  ChildComponent,
},
data() {
    return {
      items: [
        {
          id: 1,
          imgURL: '01-1.webp',
          title: 'Title1',
          descriptions: 'Lorem ipsum',
        },
        {
          id: 2,
          imgURL: '02-1.webp',
          title: 'Title2',
          descriptions: 'Lorem ipsum',
        },
      ],
    }
  }
} 
</script>

Example ChildComponentExample.vue:

<template>
  <div>
    <div>
      <img :src="imageURL" alt="Alt text" />
      <div>
        <h3> {{ title }} </h3>
        <div> {{ descriptions }} </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    imageURL: {
      type: String,
      required: true,
      default: '',
    },
    title: {
      type: String,
      required: true,
      default: 'Title',
    },
    descriptions: {
      type: String,
      required: true,
      default: 'No descriptions',
    },
  },
}
</script>

Upvotes: 3

Xufeng He
Xufeng He

Reputation: 1

<!-- 404 Not found: http://localhost:3000/assets/img/pds_main.png -->

this indicates this way correct! what wrong is your image path. look if your pds_main.png in the path: /assets/img/

Upvotes: 0

Related Questions