Astro Optimized Images With Markdown thumbnail

Astro Optimized Images With Markdown

July 26, 2024 David Teather

Table of Contents

I recently upgraded my site to a newer version of Astro that supported image optimization and I wanted to use that feature. I’ll walk you through it, and it’s a fairly quick change to improve the load times and the sizes of images you’re serving to end users.

If you’re just interested in the code here it is as a template website.

First, we need to move all of our images that we’re serving into src instead of in the public folder. The public folder contents are all directly copied over in the build folder without pre-processing.

Anywhere in your code that you have statically defined links to images like

<img src="/public/assets/my-image.png" alt="My alt" />

After moving the image from public/assets into src/assets we can replace it with the following.

---
import { Image } from "astro:assets";
import localBirdImage from '../../assets/my-image.png';
---
<Image src={localBirdImage} alt="My alt">

By using <Image> Astro will automatically optimize your image for the web at build-time, and that’s all you have to do for statically linked images.

With Dynamic Images From Blogs

This is where it gets a little bit tricker as we can’t dynamically import images from blogs, however Astro has a feature to make this possible.

In your src/content/config.ts you might have something like this.

src/content/config.ts
const blog = defineCollection({
	schema: z.object({
		heroImage: z.string().optional(), // a url like /public/assets/heroImage.png
        // ... other fields
	}),
});

For us to be able to use the image in an <Image> component, we have to update the schema to be of the image type.

src/content/config.ts
const blog = defineCollection({
	schema: ({ image }) => z.object({
		heroImage: image().optional(),
        // ... other fields
	}),
});

Next for each of your blogs update your metadata to point to the image now in the src folder.

# From
heroImage: '/public/assets/blog-placeholder-3.jpg'
# To
heroImage: '../../assets/blog-placeholder-3.jpg'

Then update any references to images in your markdown itself.

<!-- From -->
![blog placeholder](/public/assets/blog-placeholder-about.jpg)
<!-- To -->
![blog placeholder](../../assets/blog-placeholder-about.jpg)

After that, as we did before, update any references that were using <img> to use <Image>.

<!-- From -->
<img
    src={article.data.heroImage}
    alt=""
    data-pagefind-meta="image[src], image_alt[alt]"
/>
<!-- To -->
<Image
    src={article.data.heroImage}
    alt=""
    data-pagefind-meta="image[src], image_alt[alt]"
>

Then, Astro will automatically optimize all of your images!

Here’s a template website with optimized images and a search bar.

Back to blog