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.