#Astro 2.1 - Missing documentation on dynamic image imports with astro:assets

23 messages ยท Page 1 of 1 (latest)

primal cosmos
#

I was going through the new guide at https://docs.astro.build/en/guides/assets/ today, trying to migrate one of my projects to the new version.

One thing I wasn't able to figure out myself is how to use image assets specified in the frontmatter of an .mdx file.
For example, I might want to specify a thumbnail image in the frontmatter of each blog post's .mdx file.

---
title: 'Blog Post Title'
thumbnail: '../../assets/images/blog_post_1.png'
---
Mollit proident eiusmod mollit aute est pariatur duis eu enim in voluptate. Officia ipsum culpa officia eiusmod. Id voluptate consequat sit ut tempor id. Proident et nostrud consequat proident sint.

Now, let's say I want to display a list of all blog posts with their thumbnails. How do I (dynamically) import the image so I can provide it to the src attribute of the Image component?

Using a dynamic import doesn't work because Vite doesn't permit fully dynamic paths (e.g. you have to provide the file ending, ...).

posts/index.astro

---
import { Image} from 'astro:assets';

const posts: BlogPost[] = await getCollection('posts');
---

<div>
{
  posts.map((post: Post) => {
    return (
      <div>
        <Image src={post.data.thumbnail} alt="..." ????? />
      </div>
    );
  })
}
</div>

I have also tried using

src={`/_astro/images/posts/${post.data.thumbnail}`}

without any success.

I'm assuming there is a correct way to do this since the official guide uses the example of a cover image inside the schema definition. Maybe, the Assets guide on the website could be expanded with an example of how to use frontmatter images inside an .astro file.

const blogCollection = defineCollection({
  schema: z.object({
    title: z.string(),
    cover: image().refine((img) => img.width >= 1080, {message: 'Cover image must be at least 1080 pixels wide!'}),
  }),
});

Any help would be greatly appreciated!

Astro Documentation

Learn how to enable experimental asset support in Astro.

proud scroll
#

For this use case, you probably don't want to use a dynamic imports

#

As you've noticed yourself, you can use images through your schema

#

Then, when you render the entry, you can get the image from there, like such:

---
import { getEntryBySlug } from "astro:content";

const entry = await getEntryBySlug("blog", "random-post");
---

<img src={entry.cover.src} width={entry.cover.width} height={entry.cover.height} />
#

or you can pass it the Image component, if you want to optimize it:

<Image src={entry.cover} alt="My super cover!" />
cobalt sand
#

Thanks, this helped but I still can't get my image.

in my schema:

image: image().optional(),

MDX (or MD) frontmatter

image: "./remnant-coop.jpg"

but entry.data.image returns undefined.

proud scroll
#

Try image: remnant-coop.jpg, maybe?

cobalt sand
#

Nope

proud scroll
#

Not sure then, sorry. If you have a repo I can look at, that'd be great!

primal cosmos
# proud scroll As you've noticed yourself, you can use images through your schema

Thank for so you much for the help!

I managed to get the image path from the .mdx file inside the .astro file using your method. However, when I try to start the development server, I get a node error telling me that it is unable to find the image on my machine.

This is what entry.data.cover.src looks like when logged to the console.

/Users/dev/Projects/Astro_Test_Project/src/assets/images/posts/test-image.png

But when trying to build the application, this is the path Node is looking at:

/Users/dev/Projects/Astro_Test_Project/Users/dev/Projects/Astro_Test_Project/src/assets/images/posts/test-image.png

Basically, Astro takes my path from the .mdx file (relative to the assets folder) and appends it to the project directory's path. The Image component takes that path and appends it to the project directory's path a second time.

This is a really strange behavior, as I am in no place in the application joining the path myself.

Could this be related to the other issue that I am having with the new version? The migration guide mentions that Astro should automatically change <reference types="astro/client" /> to <reference types="astro/client-image" /> when starting the development server. In my case, the oppose happens: Whenever I start the dev server, <reference types="astro/client-image" /> gets changed to <reference types="astro/client" /> (even after manually changing the value).

proud scroll
#

There's currently an issue with content collections images causing wrong paths, we'll be releasing a fix today hopefully

#

(fix is already merged, just not released)

#

As for the env.d.ts issue, yeah, I've noticed that issue too, I'll try to fix it today!

primal cosmos
#

Looking forward to it and thank you again for the quick response!

proud scroll
#

No problems! Thank you for your patience while we fix up this experimental feature ๐Ÿ’ช

torpid crane
#

I also have the same error with repeated paths on Linux with astro 2.1.2. I can also confirm the env.d.ts error, it took me some time to get the client-image Version.

Thanks for the great work!

primal cosmos
#

@proud scroll

I tested out the changes in 2.1.3 and the dynamic import inside .astro files now works great.
Thank you for the quick fix ๐Ÿ™

Unfortunately, there is still an issue when using images embedded inside .mdx files.

Let me provide you with an example:

![Test Picture](../../assets/images/posts/test_picture.png)

<img
  src="/_astro/images/posts/test_picture.hash.png"
  alt="picture description"
>

At first, this example throws the error: Expected a closing tag for <img>

But once I close the <img> tag, this error appears instead:
Relative image paths are not supported in the content/ directory. Place local images in the public/ directory and use absolute paths

I based my example on the Assets (Experimental) guide on the website https://docs.astro.build/en/guides/assets/#update-your-markdown-files

Astro Documentation

Learn how to enable experimental asset support in Astro.

proud scroll
#

Yeah, MDX is currently unsupported

#

This is why it says

Relative images with automatic optimization in Markdown
without specifying MDX

#

Sorry for the confusion, MDX support is nonetheless planned

primal cosmos
#

I apologize, I just assumed it would work for MDX files as well ๐Ÿ˜…

So I am assuming the only way to get image optimization to work inside .mdx files right now is to use the <Image /> component from astro:assets?

---
import picture from '../../assets/picture.png'
import { Image } from 'astro:assets';
---

<Image
  src={picture}
  height={picture.height}
  width={picture.width}
  alt="description"
/>
proud scroll
#

Yeah, using the Image component should work

torpid crane
#

nice, thanks for the super quick fix