Search code examples
astrojs

Import an image from an Astro.props variable


How can I import an image in an astro file when the URL of the image comes from a Prop.

---
const { 
    thumbnail,
} = Astro.props.blog_entry.data;

//this works in DEV, but throws an error when executing the build command
const { default : thumbnail_url } = await import(thumbnail.url);
---
<!--- ... --->
<img src={thumbnail_url.src} alt={thumbnail.alt}/>
<!--- ... --->

During the build command, this error appears: Cannot find module 'D:\src\assets\image.jpg'.... Which is not the actual location of the file.


When I put the URL directly to the <img/> Tag like:

<img src={thumbnail.url} alt={thumbnail.alt}/>

The URL does not get parsed and the production file ends with the original string ("/src/assets/image.jpg").


Solution

  • I had a similar problem where I had to create ~100 cards from json and images are stored in src/assets/* folder

    • If you don't want image optimization by astro
      move all the image files (one which needs to be dinamically imported) into the public folder and use path relative to the public folder but you can't use the image optimization functionality of Astro since you are using img tag and not Image from astro it won't matter

    • If you want to use image optimizationthen images should be inside src\

    1: you can optimize image using other methods and then use public folder

    2: using dynamic import completely breaks either in production or dev the only working solution I got

    const images:{[index:string]:any} ={}
    await Astro.glob("/src/assets/images/*.jpg").then((files) => {
        files.forEach((file) => {
            const name = file.default.src.split(".")[0].split("/").pop()
            images[name]=file.default
        });
    });
    
    places.forEach((place)=>{
        const image = images[place.name]
        if(image)
            place.image=image
        else
            place.image = fallbackImage
    })
    
    <ul>
        {
            places.map((place) => {
                return (
                    <li>
                        <Image
                            src={place.image}
                            alt={place.name}
                            width={Math.round((100 * 16) / 9)}
                            height={100}
                            format="webp"
                            loading="lazy"
                        />
                    </li>
                );
            })
        }
    </ul>