Back to blog
Apr 16, 2025
3 min read

How to add image to Astro collection

How to add and manage image fields in an Astro content collection schema.

To add an image to a collection schema in Astro, you can use the image() helper function provided by Astro’s content collections API. This allows you to define and validate image fields in your content schema. Here’s a detailed guide on how to implement this:

1. Basic Image Field

To add a basic image field to your collection schema, you can use the image() function within your schema definition:

import { defineCollection, z } from 'astro:content';

const blogCollection = defineCollection({
  type: 'content',
  schema: ({ image }) => z.object({
    title: z.string(),
    date: z.date(),
    featuredImage: image(), // This defines an image field
  }),
});

export const collections = {
  blog: blogCollection,
};

In this example, featuredImage is defined as an image field. The image() function is destructured from the schema context and used directly.

schema: ({ image }) => z.object({

This is how to get the instance of the collection image helper.

2. Optional Image Field

If you want to make the image field optional, you can use the .optional() method:

schema: ({ image }) => z.object({
  // ... other fields
  featuredImage: image().optional(),
}),

3. Image Field with Additional Validation

You can add extra validation to your image field using Zod’s methods:

schema: ({ image }) => z.object({
  // ... other fields
  featuredImage: image()
    .refine((img) => img.width >= 1080, {
      message: "Image must be at least 1080px wide",
    }),
}),

4. Multiple Image Fields

For collections that require multiple images, you can define multiple image fields:

schema: ({ image }) => z.object({
  // ... other fields
  featuredImage: image(),
  galleryImages: z.array(image()).min(1).max(5),
}),

This example includes a featuredImage and an array of galleryImages with a minimum of 1 and maximum of 5 images.

5. Specifying Image Directory

To organize your images, you can specify a directory for your images in the Astro config:

// astro.config.mjs
export default defineConfig({
  // ... other config
  content: {
    // ... other content config
    assets: 'src/assets',
  },
});

Then, in your content files, reference images relative to this directory:

---
title: My Blog Post
featuredImage: ./images/featured.jpg
---

6. Using Images in Components

After defining image fields in your schema, you can use them in your Astro components:

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

const blogPost = await getEntry('blog', 'my-blog-post');
---


7. Handling Image Arrays

If you’ve defined an array of images, you can map over them in your component:

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

const blogPost = await getEntry('blog', 'my-blog-post');
---


  {blogPost.data.galleryImages.map((img) => (
    
  ))}

By following these steps, you can effectively add and manage image fields in your Astro content collection schemas. This approach ensures type safety, enables validation, and integrates seamlessly with Astro’s built-in image optimization features.