How to pass dynamic image url in nuxt project
Asked Answered
C

13

14

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.

Cascarilla answered 25/6, 2019 at 7:51 Comment(2)
What is "convertUrl"? Is it a method, and if so please show it.Buckles
@Buckles Sorry, It was my mistake. I convert 'convertUrl' to props nameCascarilla
H
29

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>
Heading answered 24/12, 2019 at 17:2 Comment(2)
This should be marked as correct answer. Also in my case I just passed an array of objects (each object represent an img) and pass a key with imgSrc and value of require("path/to/img")Atomism
This blog post explains how this works: blog.lichter.io/posts/dynamic-images-vue-nuxtCentrosymmetric
L
3

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>
Lisa answered 23/12, 2020 at 6:45 Comment(0)
R
2

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

<img :src="require(`~/assets/img/${image}.jpg`)" />
Roodepoortmaraisburg answered 15/8, 2022 at 20:38 Comment(0)
R
2

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>
Representative answered 21/5, 2023 at 7:25 Comment(0)
M
1

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.

Madera answered 22/5, 2023 at 21:51 Comment(0)
D
0
<!-- 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/

Dubbin answered 25/6, 2019 at 8:22 Comment(0)
G
0

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>
Gripe answered 25/6, 2019 at 8:27 Comment(1)
The question was about using local images from /assets not statically hosted images with fixed URLWebb
S
0

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

Secondbest answered 26/6, 2019 at 4:21 Comment(3)
What is static folder and assets folder different? And why assets folder isn't a static folder?Cascarilla
Well assets folder will be processed by webpack when you npm run generate or npm run bulid whereas static folder will not. They both have their pros and cons. you can read more in [#48808682Secondbest
static folder is not good for images because if you load the SPA with a path (www.spa.com/PATH) it won't be able to find any images because everything in static is '/' but it will search in /PATH.Hotfoot
P
0

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>
Plassey answered 6/11, 2019 at 12:25 Comment(0)
H
0

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">
Hypostasize answered 25/7, 2022 at 2:7 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Hasen
C
0

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" />
Crutcher answered 17/11, 2022 at 21:37 Comment(0)
I
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" />

Intercontinental answered 7/2 at 9:30 Comment(0)
W
0

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

Webb answered 21/6 at 17:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.