#Dynamic Image import?

46 messages · Page 1 of 1 (latest)

flint dawn
#

How can I use dynamic urls for Image/Picture element? For example to load a sequence of images?

{[1, 2, 3].map(index => <Image src={import(`../images/${index}.jpeg`)}  />}
trail valley
#

Should work. For remote images or images in the public folder you can also use
<Image src={/myfolder/${number}.jpg} ... />

#

You should try to explain your problem better and even better create a reproducible example with http://astro.new

fluid ice
#

If they aren't in numerical order, but are all in the same directory, and you want the whole directory, you could use node's fs.

flint dawn
#

@trail valley True, the public folder would work, but I want to colocate the images with their content files inside src.
@fluid ice Yep, I’m using fs or import.meta.glob to read all images from a folder.

I figured it out how to use dynamic paths for src


{[1, 2, 3].map(index => <Image src={new URL(`../images/${index}.jpeg`, import.meta.url).href}  />}

fluid ice
#

I'm in a similar issue with you right now except my problem is on the other end of obtaining what the end-time file name will be to utilize in other locations. I'll watch for a solid answer from someone 👀

flint dawn
fluid ice
#

So that actually creates its own transformation on the spot and when I build the site, it doesn't seem to do it properly because the output still 404s

#

<meta property="og:image" content="/_image?w=200&#38;h=200&#38;href=..%2F..%2Fimages%2Fresearches%2F33">
Is what it looks like after building

flint dawn
#

I see!

#

Try this:

const image = "../images/something.jpeg"
const { src } = await getImage({
  src: new URL(image, import.meta.url).href,
  width: 300,
  aspectRatio: "1/1"
});
#

I think you need to also use new URL() to get an absolute path (file system). Otherwise it’s just that relative path as you’ve experienced.

fluid ice
#

Ahh that would make sense. I just left the house for class so I'll try it out when I can.

flint dawn
#

Works for me. No idea what all that means but it’s awesome that it works and has been thought about. Not even sure where I found out about that URL thing?

fluid ice
#

Okay I might work but I think it just doubled my images because I already create all of these once haha

#

Which is why I was hoping to be able to access the already made image

flint dawn
#

True… I guess it’s a bit of a conflict.

#

I’m making a reproduction for my case. Maybe it’s useful anyway.

fluid ice
#

Would be nice if you could toggle the suffix added to each image file.

flint dawn
#

Okay I see… the build succeeds but the images don’t show up… hmm…

fluid ice
#

Okay so I'm not going crazy.

#

It also seems redundant to generate the images twice if you already use them, hence it would be nice to be able to toggle them and keep folder structure so you could just assume the file name after build.

flint dawn
#

The images are copied (not resized) to the dist folder … but with some chunk suffix that doesn’t match

fluid ice
#

Correct. #integrations message

#

I threw that message out there last night when I first started running into these problems.

#

I think it would be beneficial to allow you to toggle those chunk suffixes because if it keeps folder structure, then you could keep the original file name.

flint dawn
#

Okay I found another way that has some limitations but works like that:

#

We can install vite-plugin-dynamic-import which allows us to use expressions in the import statement. But there are two requirements that suck: the expression needs to start with ./ or ../ (fair enough) and has to end with a file extension. But if you can assume that all files are in the same folder and have the same extension, this works for me:

<Image src={import(`../images/${name}.jpeg`)} width={128} height={128} quality={100} alt="" />
fluid ice
#

Now is this before or after build time? Because my images will start as a png but get transformed to a webp.

I'm also not sure if you can use an image directory in a meta tag? Unless that gets transformed to an end-url at build time?

flint dawn
#

In the src you need to define the original extension and then you can use format={'webp'} which will result in webp files in the dist folder.

fluid ice
#

Gotcha, it would still just double the image count, but it works.

flint dawn
#

Yeah I might turn this into an issue describing what I want and possible solutions that all aren’t perfect.

But with this solution I can at least load all .jpeg images from a folder, get their names, and then use those in my template loops:

const images = Object.keys(import.meta.glob("../images/*.jpeg")).map((image) =>
  image.replace("../images/", "").replace(".jpeg", "")
);

#

Feels hacky but what do I know

fluid ice
#

Makes sense 👍 . Let's hope we can get some easier solutions for this in the future.

fluid ice
#

I was thinking about it, and another solution (though not ideal) would be to run all the images through the processor and convert them to webps, and then just move them to the public directory.

#

Still would be nice to have an option to keep folder structure and strip suffixes.

tired goblet
#

I’d love to see this as a feature

restive flare
livid fulcrum
restive flare
#

Okay thanks yeah, I get stuck at importing the image as I need to do it based on the value in the page's frontmatter. This topic seemed to be about exactly that.

restive flare
#

I feel I'm so close! But how do we get it into a meta tag, like:

---
import { getImage } from "astro:assets";
const {previewImageOGSrc} = Astro.props
const previewImageOG = await getImage({src: previewImageOGSrc, format: 'webp',   height: 1600,  width: 900,})
---
<meta property="og:image" content={previewImageOG.src} />

At some point I need to import the image, but that normally needs to be at the top of the script, which I can't do, because the path is only known via the component props.

copper hawk
#

See the link I sent you