🌐
GitHub
github.com › withastro › roadmap › discussions › 975
Include an image's absolute URL in the ImageMetaData when images are processed in Content Collections to allow @vercel/og to render Astro's images · withastro/roadmap · Discussion #975
Once processed by Astro, Images in Content Collection have the following form. type ImageMetaData = { src: string; width: number; height: number; format: "png" | "jpg" | "jpeg" | "tiff" | "webp" | "gif" | "svg" | "avif"; }
Author   withastro
🌐
Astro Documentation
tanggd.github.io › en › guides › integrations-guide › image
@astrojs/image 🚀 Astro Documentation
Type: string | ImageMetadata | Promise<ImageMetadata> Required: true · Source for the original image file. For images located in your project’s src: use the file path relative to the src directory. (e.g. src="../assets/source-pic.png") For images located in your public directory: use the URL path relative to the public directory. (e.g. src="/images/public-image.jpg") For remote images, provide the full URL. (e.g. src="https://astro.build/assets/blog/astro-1-release-update.avif") Section titled alt ·
Discussions

astro:assets doesn't export ImageMetadata, making it hard to pass images as props.
Astro Info Astro v4.12.2 Node v20.15.1 System macOS (arm64) Package Manager bun 1.1.17 Output static Adapter none Integrations astro-icon @astrojs/preact auto-import astro-embed astro-expressive-co... More on github.com
🌐 github.com
2
July 21, 2024
hey anyone knows how to fix astro Image component type error
Hello Everyone getting this error on build time using astro image component and cover is image fetched from content matter export const posts =… More on reddit.com
🌐 r/astrojs
4
1
June 6, 2024
@astrojs/image overrides import type for images (including code in other frameworks like react)
importing images in React gives typescript error because @astrojs/image overrides the type (but not value) from string to ImageMetadata More on github.com
🌐 github.com
10
January 21, 2023
astrojs - Import an image from an Astro.props variable - Stack Overflow
If you are using the contents folder to store the data of your places, you can use the image validator that imports and transforms the string into imageMetadata. Docs here. 2023-10-16T04:44:59.633Z+00:00 ... Thank you. With your solution, I was able to use the Astro Picture component while ... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Astro
docs.astro.build › en › reference › modules › astro-assets
Image and Assets API Reference - Astro Docs
Type: 'fill' | 'contain' | 'cover' | 'none' | 'scale-down' | string | undefined Added in: astro@5.0.0 · Defines a list of allowed values for the object-fit CSS property, extensible with any string.
🌐
Cosmic Themes
cosmicthemes.com › blog › astro-dynamic-image-imports
Dynamically Import Images in Astro - Cosmic Themes
April 20, 2024 - const { imagePath, description } = Astro.props as Props; // image path looks like "src/assets/img1.jpg" const images = import.meta.glob<{ default: ImageMetadata }>("/src/assets/*.{jpeg,jpg,png,gif}"); --- <div> <Image src={images[imagePath]()} alt={description} width={600} /> <p>{description}</p> </div> Templates with tons of features others leave out.
🌐
Uploadcare
uploadcare.com › web performance category › how to optimize images in astro: a step-by-step guide
How to optimize images in Astro: A step-by-step guide | Uploadcare
August 29, 2025 - First, in the components directory of your project, create a new file called CustomImageComponent.astro and add the following code to it: Copy · --- import type { ImageMetadata } from 'astro'; import { getImage } from 'astro:assets'; interface Props { imageUrl: string | ImageMetadata; alt: string; } const { imageUrl, alt } = Astro.props; const image = await getImage({ src: imageUrl, }); --- <uc-img src={imageUrl} alt={alt} /> <style> uc-img { --uc-img-pubkey: 'YOUR_PUBLIC_KEY'; --uc-img-breakpoints: '480, 800, 1200'; } </style> <script src="https://cdn.jsdelivr.net/npm/@uploadcare/file-uploader@v1/web/uc-img.min.js" type="module"></script> The code above fetches the image passed to the getImage function and renders the image using Uploadcare’s uc-img component for optimization.
🌐
GitHub
github.com › withastro › astro › issues › 11521
astro:assets doesn't export ImageMetadata, making it hard to pass images as props. · Issue #11521 · withastro/astro
July 21, 2024 - import type { ImageFunction } from 'astro:content' type ImageMetadata = ReturnType<ImageFunction>['_output']
Author   jcayzac
🌐
Keystatic
keystatic.com › docs › recipes › astro-images
Use Astro's Image component with the Keystatic image field - Docs | Keystatic
You need to configure the Zod content collection schema in Astro, and use the image helper for the image metadata transformation to work.
🌐
Reddit
reddit.com › r/astrojs › hey anyone knows how to fix astro image component type error
r/astrojs on Reddit: hey anyone knows how to fix astro Image component type error
June 6, 2024 - Type '{ src?: string; width?: number; height?: number; format?: "png" | "jpg" | "jpeg" | "tiff" | "webp" | "gif" | "svg" | "avif"; }' is not assignable to type 'string | ImageMetadata | Promise<{ default: ImageMetadata; }>'. Type '{ src?: string; width?: number; height?: number; format?: "png" | "jpg" | "jpeg" | "tiff" | "webp" | "gif" | "svg" | "avif"; }' is not assignable to type 'ImageMetadata'.ts(2322) The expected type comes from property 'src' which is declared here on type 'IntrinsicAttributes & Props' types.d.ts(159, 5): ... Screw you. *Strips your Astro*
Find elsewhere
🌐
Astro
docs.astro.build › en › guides › images
Images - Astro Docs
Local images must be imported from the relative path from the existing .astro file, or you can configure and use an import alias. Then, you can access the image’s src and other properties to use in the <img> tag. Imported image assets match the ImageMetadata type and have the following signature:
🌐
GitHub
github.com › withastro › astro › issues › 5924
@astrojs/image overrides import type for images (including code in other frameworks like react) · Issue #5924 · withastro/astro
January 21, 2023 - import logo from './dummy.png'; export default function Counter() { // img is expecting a string but we get ImageMetadata type instead return ( <img src={logo} /> ); }
Author   JLarky
🌐
Astro
docs.astro.build › en › recipes › build-custom-img-component
Build a custom image component - Astro Docs
src/components/MyCustomImageComponent.astro · --- import type { ImageMetadata } from "astro"; import { getImage } from "astro:assets"; interface Props { mobileImgUrl: string | ImageMetadata; desktopImgUrl: string | ImageMetadata; alt: string; } const { mobileImgUrl, desktopImgUrl, alt } = Astro.props; const mobileImg = await getImage({ src: mobileImgUrl, format: "webp", width: 200, height: 200, }); const desktopImg = await getImage({ src: desktopImgUrl, format: "webp", width: 800, height: 200, }); --- Create a <picture> element that generates a srcset with your different images based on your desired media queries.
🌐
Astro
docs.astro.build › en › reference › image-service-reference
Image Service API - Astro Docs
Type: (url: string, imageConfig: AstroConfig[‘image’] ) => Omit<ImageMetadata, ‘src’ | ‘fsPath’> | Promise<Omit<ImageMetadata, ‘src’ | ‘fsPath’>> Added in: astro@6.0.0
🌐
Reddit
reddit.com › r/astrojs › looking for advice on optimising images with astro, content collections, and mdx
r/astrojs on Reddit: Looking for advice on optimising images with Astro, content collections, and MDX
June 28, 2025 -

I've been building a blog/portfolio site using Astro with content collections and MDX. I'm trying to optimise images inside blog posts. Each post has multiple images, and I use a custom Astro component to display them with detailed captions in MDX files.

The issue is that Astro’s built-in Image component only works with statically imported images. That doesn’t play well with content collections and MDX, where importing each image manually isn’t practical, especially when posts have lots of images or grouped images with text blocks. Something would be limiting with just markdown syntax.

From what I’ve found, the dynamic import method using import.meta.glob() works, but it requires all images to live in a single folder. I’d prefer keeping assets organized inside each content folder (e.g., separate assets for blog/post vs. work), which that approach doesn’t really support.

The only other option seems to be putting everything in /public and using external tools for optimisation, but that feels like a workaround.

Has anyone faced this issue? How are you guys handling image optimisation in Astro with MDX and content collections?

Top answer
1 of 5
3
I'm working on a webcomic site right now that displays a lot of images and none of them are in the public folder, they're all in src with their md/mdx related pages. In an mdx file if you're using `![alt](src)` to display an image it should come up optimized (i.e. webp). A lot of my images are also listed in the frontmatter and use the image() schema so astro can build ImageMetadata for them.
2 of 5
2
I've just done something very similar. Reddit won’t let me comment from my laptop so excuse the formatting - had to paste from my phone. I have an Astro site powered by MDX and Keystatic where we often have a number of images within components in the MDX content that use the Astro Image component for optimisation. We’re able to store the images in individual folders for each item in the collection in the assets directory. Eg an image for a blog post created at posts/my-post.mdx has images stored in assets/posts/my-post/some-image.jpg. It’s worth noting too that the assets folder is just a convention and if you’d rather store the images with your mdx files you probably could! For example we have a FullWidthImage.astro component which we render in our MDX file like this: Then FullWidthImageBlock.astro uses dynamic images imports like this: --- import { Image } from "astro:assets"; import type { ImageMetadata } from "astro"; import type { FullWidthImageBlockComponentProps as Props } from "@lib/content-blocks/full-width-image-block.definition"; const { imagePath, altText } = Astro.props as Props; // Dynamically image import via glob const images = import.meta.glob<{ default: ImageMetadata }>( "/src/assets/images/**/**/*.{jpeg,jpg,png,gif,webp,svg}", ); // Optinally throw an error if the image isn't found if (imagePath && !images[imagePath]) { throw new Error( `"${imagePathFromProps}" does not exist in glob: "/src/assets/images/**/**/*.{jpeg,jpg,png,gif,webp,svg}"`, ); } // Optionally handle missing alt text const imageAlt = altText || "Image"; if (!altText && imagePath) { console.warn( `[FullWidthImageBlock] Missing alt text for image: ${imagePathFromProps}. Using fallback.`, ); } --- { imagePath && images[imagePath] && ( ) } Our components are used across multiple collections so we're just being lazy and globbing the whole assets folder and finding the image required from there. If you end up with a LOT of images (e.g. 1000+) this might not be the best in terms of dev mode performance, but it's basically just using a key value look up so is pretty efficient and it all happens at build time anyway. You could always pass a prop for the collection and post and only glob a must smaller number of assets. Anyway hope that's helpful!
🌐
npm
npmjs.com › package › @astrojs › image
@astrojs/image - npm
August 30, 2023 - Type: string | ImageMetadata | Promise<ImageMetadata> Required: true · Source for the original image file. For remote images, provide the full URL. (e.g. src="https://astro.build/assets/blog/astro-1-release-update.avif") For images located in your project's src/: use the file path relative to the src/ directory.
      » npm install @astrojs/image
    
Published   Aug 30, 2023
Version   0.18.0
Author   withastro
🌐
Astrojs
astrojs.cn › en › reference › modules › astro-assets
Image and Assets API Reference - Astro 文档
src="/_astro/my_image.hash.webp" width="1600" height="900" decoding="async" loading="lazy" alt="A description of my image." /> Section titled Image properties · The <Image /> component accepts the following listed properties and responsive image properties in addition to all properties accepted by the HTML <img> tag. Section titled src (required) Type: ImageMetadata | string | Promise<{ default: ImageMetadata }> The format of the src value of your image file depends on where your image file is located: Local images in src/ - you must also import the image using a relative file path or configure and use an import alias.
🌐
GitHub
github.com › withastro › docs › blob › main › src › content › docs › en › recipes › dynamically-importing-images.mdx
docs/src/content/docs/en/recipes/dynamically-importing-images.mdx at main · withastro/docs
--- import type { ImageMetadata } from 'astro'; import { Image } from 'astro:assets'; interface Props { imagePath: string; altText: string; name: string; age: number; } const { imagePath, altText, name, age } = Astro.props; const images = import.meta.glob<{ default: ImageMetadata }>('/src/assets/*.{jpeg,jpg,png,gif}') --- Use the props to create the markup for your card component.
Author   withastro
🌐
Julia Packages
juliapackages.com › p › imagemetadata
ImageMetadata · Julia Packages
ImageMetadata is a simple package providing utilities for working with images that have metadata attached. For example, you might want to associate an image with the date on which the picture was taken, or an MRI scan with patient data, or an ...
🌐
GitHub
github.com › withastro › docs › blob › main › src › content › docs › en › recipes › build-custom-img-component.mdx
docs/src/content/docs/en/recipes/build-custom-img-component.mdx at main · withastro/docs
--- import type { ImageMetadata } from "astro"; import { getImage } from "astro:assets"; interface Props { mobileImgUrl: string | ImageMetadata; desktopImgUrl: string | ImageMetadata; alt: string; } const { mobileImgUrl, desktopImgUrl, alt } = Astro.props; const mobileImg = await getImage({ src: mobileImgUrl, format: "webp", width: 200, height: 200, }); const desktopImg = await getImage({ src: desktopImgUrl, format: "webp", width: 800, height: 200, }); --- <picture> <source media="(max-width: 799px)" srcset={mobileImg.src} /> <source media="(min-width: 800px)" srcset={desktopImg.src} /> <img src={desktopImg.src} alt={alt} /> </picture>
Author   withastro