As an example, I have an Astro app with a collection /collections/artworks
where each artwork
specifices a cover image via the frontmatter cover: '../assets/artworks/1-hello/cover.png
- the file lies at /src/assets/artworks/1-hello/cover.png
. I am trying to use Astro's asset support.
Then in my template, I am looping through all the artworks and have <Image width={400} src={artwork.data.cover} alt={artwork.data.coverAlt} />
which does not work and fails to find the file.
Trying to import it inline seems to fail <Image width={400} src={import(artwork.data.cover)} alt={artwork.data.coverAlt} />
with the error "Received unsupported format undefined
from undefined
", assuming that it's just not resolving.
However, if I import the image explicitly with the same path as specified in the markdown, it works:
import cover from "../assets/artworks/1-hello/cover.png"
<Image src={cover} ... />
How can I loop through a collection and dynamically import images specified in the markdown accordingly?
To use images in Markdown frontmatter with Astro’s assets feature, you need to use the image
helper in your content collection schema.
Assuming your current schema looks something like this:
// src/content/config.ts
import { defineCollection, z } from "astro:content";
export const collections = {
artworks: defineCollection({
schema: z.object({
cover: z.string(),
}),
}),
};
You need to update the schema
to be a function, and use the image
parameter as the schema type for cover
:
// src/content/config.ts
import { defineCollection, z } from "astro:content";
export const collections = {
artworks: defineCollection({
schema: ({ image }) => z.object({
cover: image(),
}),
}),
};
This will import the image for you behind the scenes, so that you can pass artwork.data.cover
directly to the <Image>
component.