Skip to main content
Astro provides powerful built-in asset handling for images and other media. The assets system optimizes images automatically, generates multiple formats, and provides a great developer experience with type safety.

Image Component

The Image component from astro:assets optimizes images at build time with automatic format conversion, resizing, and lazy loading.
src/pages/index.astro
---
import { Image } from 'astro:assets';
import heroImage from '../assets/hero.png';
---

<Image src={heroImage} alt="Hero image" />
Images are optimized during the build process, generating multiple sizes and formats for better performance.

Local Images

Import local images from your project to get type safety and automatic optimization:
---
import { Image } from 'astro:assets';
import profilePic from '../assets/profile.jpg';
import logo from '../assets/logo.png';
---

<Image 
  src={profilePic} 
  alt="Profile picture"
  width={300}
  height={300}
/>

<Image 
  src={logo} 
  alt="Company logo"
  format="webp"
  quality="high"
/>

Remote Images

For remote images, specify dimensions explicitly:
---
import { Image } from 'astro:assets';
---

<Image
  src="https://example.com/image.jpg"
  alt="Remote image"
  width={800}
  height={600}
  format="avif"
/>
Remote images require explicit width and height attributes. Configure allowed remote domains in your config.

Image Properties

The Image component accepts various properties for optimization:
src
ImageMetadata | string
required
Image source - local import or remote URL
alt
string
required
Alternative text for accessibility
width
number
Target width in pixels. Required for remote images.
height
number
Target height in pixels. Required for remote images.
format
'avif' | 'webp' | 'png' | 'jpg' | 'svg'
Output format. Defaults to optimized format.
quality
number | 'low' | 'mid' | 'high' | 'max'
Compression quality. Default: ‘mid’
densities
number[]
Pixel density descriptors for responsive images
widths
number[]
Generate multiple widths for srcset

Example with All Properties

---
import { Image } from 'astro:assets';
import banner from '../assets/banner.jpg';
---

<Image
  src={banner}
  alt="Product banner"
  width={1200}
  height={600}
  format="webp"
  quality="high"
  loading="lazy"
  decoding="async"
  class="banner-image"
/>

Picture Component

Use the Picture component for art direction and multiple formats:
---
import { Picture } from 'astro:assets';
import hero from '../assets/hero.jpg';
---

<Picture
  src={hero}
  alt="Hero image"
  formats={['avif', 'webp', 'jpg']}
  widths={[400, 800, 1200]}
  sizes="(max-width: 800px) 100vw, 800px"
/>
This generates:
  • Multiple format versions (AVIF, WebP, JPEG)
  • Multiple sizes for responsive images
  • Automatic <picture> element with <source> tags
Use Picture for responsive images with art direction. Use Image for simple cases.

Image Service

Astro uses Sharp by default for image optimization. You can configure or replace the image service:
astro.config.mjs
import { defineConfig } from 'astro/config';

export default defineConfig({
  image: {
    service: {
      entrypoint: 'astro/assets/services/sharp',
      config: {
        limitInputPixels: false
      }
    },
    // Configure remote image domains
    domains: ['images.example.com'],
    remotePatterns: [{ protocol: 'https' }]
  }
});

Available Services

High-performance Node.js image processing:
import { defineConfig } from 'astro/config';

export default defineConfig({
  image: {
    service: {
      entrypoint: 'astro/assets/services/sharp'
    }
  }
});

getImage API

For programmatic image optimization, use the getImage function:
---
import { getImage } from 'astro:assets';
import background from '../assets/background.jpg';

const optimizedImage = await getImage({
  src: background,
  width: 1920,
  height: 1080,
  format: 'webp',
  quality: 'high'
});
---

<div style={`background-image: url(${optimizedImage.src})`}>
  Content here
</div>

Return Value

The getImage function returns an object with:
interface GetImageResult {
  src: string;              // Optimized image URL
  srcSet: {
    values: string[];       // srcset values
    attribute: string;      // Complete srcset attribute
  };
  attributes: Record<string, any>; // HTML attributes
  options: ImageTransform;  // Transform options used
}

Images in Markdown

Reference images in Markdown and MDX files:
src/content/blog/post.md
---
title: My Post
---

![Alt text](../../assets/image.jpg)
Or use the Image component in MDX:
src/content/blog/post.mdx
---
title: My Post
---
import { Image } from 'astro:assets';
import screenshot from '../../assets/screenshot.png';

# My Post

<Image src={screenshot} alt="App screenshot" />

Responsive Images

Generate responsive images with multiple sizes:
---
import { Image } from 'astro:assets';
import product from '../assets/product.jpg';
---

<Image
  src={product}
  alt="Product image"
  widths={[400, 800, 1200]}
  sizes="(max-width: 600px) 400px, (max-width: 1200px) 800px, 1200px"
/>
This generates:
<img
  src="/product-800.webp"
  srcset="
    /product-400.webp 400w,
    /product-800.webp 800w,
    /product-1200.webp 1200w
  "
  sizes="(max-width: 600px) 400px, (max-width: 1200px) 800px, 1200px"
  alt="Product image"
/>

Image Layouts

Control how images scale and fit:
<Image
  src={image}
  alt="Constrained image"
  width={800}
  layout="constrained"
/>
Image scales down on smaller screens but never exceeds its specified width. Best for most use cases.
Image maintains exact dimensions at all screen sizes. Best for avatars, icons, and UI elements.
Image always fills its container width. Best for hero images and banners.

Background Images

Optimize background images using getImage:
---
import { getImage } from 'astro:assets';
import bg from '../assets/background.jpg';

const backgroundImage = await getImage({
  src: bg,
  format: 'webp',
  quality: 80
});
---

<section style={`background-image: url(${backgroundImage.src})`}>
  <h1>Hero Section</h1>
</section>

<style>
  section {
    background-size: cover;
    background-position: center;
  }
</style>

Other Assets

Fonts

Import and reference fonts:
---
import fontFile from '../assets/fonts/custom-font.woff2';
---

<style>
  @font-face {
    font-family: 'CustomFont';
    src: url({fontFile}) format('woff2');
  }
</style>

Videos

Reference video files:
---
import video from '../assets/demo.mp4';
---

<video controls>
  <source src={video} type="video/mp4" />
</video>

Public Directory

For assets that shouldn’t be processed, use the public/ directory:
public/
  favicon.ico
  robots.txt
  static-image.png
Reference them with absolute paths:
<img src="/static-image.png" alt="Static image" />
<link rel="icon" href="/favicon.ico" />
Files in public/ are copied as-is to the build output without processing.

Performance Best Practices

1

Use modern formats

Enable AVIF and WebP for better compression:
<Picture
  src={image}
  formats={['avif', 'webp', 'jpg']}
  alt="Optimized image"
/>
2

Lazy load off-screen images

<Image
  src={image}
  alt="Lazy loaded"
  loading="lazy"
/>
3

Set appropriate quality

<Image
  src={image}
  quality="mid" // or 70-80 for custom
  alt="Quality optimized"
/>
4

Generate responsive sizes

<Image
  src={image}
  widths={[400, 800, 1200]}
  sizes="(max-width: 640px) 400px, (max-width: 1024px) 800px, 1200px"
  alt="Responsive image"
/>

TypeScript Support

Images imports are fully typed:
import type { ImageMetadata } from 'astro';
import image from '../assets/image.jpg';

// image is typed as ImageMetadata
const metadata: ImageMetadata = image;

console.log(metadata.width);  // number
console.log(metadata.height); // number
console.log(metadata.format); // string
console.log(metadata.src);    // string

Markdown

Use images in Markdown content

Content Collections

Manage images in collections

Configuration

Configure image service

Performance

Performance optimization guide

Build docs developers (and LLMs) love