Use Astro's Image component with the Keystatic image field
Astro provides a built-in <Image />
component that helps display optimized versions of local images.
This guides walks you through the configuration needed to use the <Image />
component with the image field in Keystatic.
The assets directory in Astro
To make use of Astro's <Image />
component, you need to store your images in the src/assets
directory in your project.
You can do so using the directory
option in the Keystatic config.
We recommend creating a path alias for the src/assets
directory in your .tsconfig.json
file — it simplifies referencing the path to that directory:
// .tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@assets/*": ["./src/assets/*"],
},
}
}
Standalone image field
Images stored in a standalone image
field (not inside a MDX or Markdoc document) will be stored in your frontmatter data in Astro's content collections.
You need to configure the Zod content collection schema in Astro, and use the image helper for the image metadata transformation to work.
Refer to this section of the Astro documentation for more information.
Using the path alias suggested above, you can setup your image field options like this:
image: fields.image({
label: 'Image',
directory: 'src/assets/images/posts',
// Use the @assets path alias
publicPath: '@assets/images/posts/'
})
As long as the image path stored is within the src/assets
directory, Astro will be able to process it into image metadata that the <Image />
component can use.
Images inside MDX or Markdoc fields
Images uploaded via the MDX of Markdoc fields can be configured the same way as standalone image fields via the options
object:
content: fields.mdx({
label: 'Content',
options: {
image: {
directory: 'src/assets/images/posts',
// Use the @assets path alias
publicPath: '@assets/images/posts/'
}
}
})
Just like standalone image fields, you will need to configure the Zod schema with the image helper for the image metadata transformation to work.
Content component images
Using Astro assets within content components is a little more complicated.
Since the image is not stored in the frontmatter data but directly within the content body, you'll need to dynamically import the image inside the component you're using to render that content component.
The publicPath
for those images must start with /src/assets
for the dynamic import to work in Astro 😅
Here's how you should configure the image field inside content components:
// Inside a MDX or Markdoc field...
captionImage: block({
label: 'Caption Image',
schema: {
image: fields.image({
label: 'Image',
directory: 'src/assets/images/posts',
// start with /src/assets
publicPath: '/src/assets/images/posts/'
}),
// other fields...
}
})
Read the Astro guide on dynamic image imports for details on the implementation.