Overview
astro:assets optimizes images with Sharp (the default service). <Image /> transforms a local or authorized remote image, infers dimensions from the file to prevent layout shift, and outputs WebP by default; <Picture /> adds a <picture> element with multiple formats. Both default to loading="lazy" and decoding="async" and require alt (use alt="" for decorative images).
Import local images and let Astro infer the size
Keep source images in src/assets/ and import them. Astro reads width and height from the file.
---
import { Image } from "astro:assets";
import hero from "../assets/hero.jpg";
---
<Image src={hero} alt="A description of the image" />Pass format="avif" to change the output format. Images in public/ are served as is and never transformed; put favicons, pre-sized OG images, and files referenced by external URLs there. A large hero JPEG in public/ is the usual cause of a heavy Lighthouse image warning. Remote and public/ images need explicit width and height, or inferSize, which fetches remote dimensions only for authorized domains.
Use <Picture /> for several formats and widths
<Picture /> takes formats (default ["webp"]) and a fallbackFormat (PNG for static images). Pass widths and sizes together, because without sizes the browser assumes 100vw.
<Picture src={hero} widths={[400, 800, 1200]} sizes="(max-width: 720px) 100vw, 800px"
formats={["avif", "webp"]} alt="Hero image" />Mark the LCP image with priority
Add priority to the above-the-fold image (Astro 5.10+). It sets loading="eager", decoding="sync", and fetchpriority="high". You can still override each attribute. Use it on one image per page.
<Image src={hero} alt="Hero" priority />Let responsive layout generate srcset and sizes
Set layout to constrained, full-width, or fixed on a component, or image.layout in the config for a default (Astro 5.10+). Astro then generates srcset and sizes for you. Enable image.responsiveStyles: true to add the matching resizing CSS.
<Image src={hero} alt="Hero" layout="constrained" width={800} height={600} />Allowlist remote image sources
Only authorized remote images are optimized. Add hosts to image.domains or patterns to image.remotePatterns in astro.config.mjs.
export default defineConfig({
image: {
domains: ["cdn.sanity.io"],
remotePatterns: [{ protocol: "https", hostname: "images.ctfassets.net" }],
},
});Prefer a specific hostname over a bare protocol pattern, which authorizes every HTTPS host. On Cloudflare, the adapter’s default image service is cloudflare-binding (adapter v13), not Sharp.