Skip to content

Images

Astro has a built-in image optimisation pipeline. Always use it - never use plain <img> tags for content images.


---
import { Picture } from 'astro:assets';
import heroImg from '../assets/hero.jpg';
---
<Picture
src={heroImg}
widths={[640, 1280, 1920]}
sizes="100vw"
formats={['avif']}
quality={65}
alt="Descriptive alt text"
loading="eager"
fetchpriority="high"
/>

Use <Picture> (not <Image>) - it generates <source> elements for multiple formats and sizes.


<Picture
src={img}
widths={[640, 1280, 1920]}
sizes="100vw"
formats={['avif']}
quality={65}
alt="..."
loading="eager"
fetchpriority="high"
/>

loading="eager" + fetchpriority="high" ensures the browser starts downloading this image immediately. Required for good LCP (Largest Contentful Paint) scores.

<Picture
src={img}
widths={[375, 640]}
sizes="(min-width: 640px) 640px, 100vw"
formats={['avif']}
quality={65}
alt="..."
loading="lazy"
/>
loading="lazy"

Never use loading=”eager” on images below the fold - it hurts performance.


Always use formats={['avif']}. AVIF is typically 50-80% smaller than JPEG at equivalent quality. All modern browsers support it. Astro falls back to the original format automatically for older browsers.


Every image must have meaningful alt text. Empty alt="" is only correct for decorative images that add no information.

Bad: alt="image", alt="photo", alt="img_1234.jpg"
Good: alt="Swaroop Bungalow office exterior in Panchgani"


  • src/assets/ - images that go through Astro’s optimisation pipeline (use with <Picture>)
  • public/ - images served as-is (OG image, favicon, logo, files linked directly)

  • Not processed by Astro - lives in public/ and is served as-is
  • Must be exactly 1200 x 630 pixels
  • Keep under 300 KB (WhatsApp limit)
  • After changing it, use the Facebook debugger to clear the social preview cache