Photographic content uses Astro’s built-in astro:assets pipeline so builds emit resized WebP (by default) with srcset / sizes.
Where files live
| Location | Use for |
|---|---|
src/assets/images/ |
Photos / raster images that should be optimized |
public/images/ |
SVGs, logos, favicons, OG files, raw URL assets |
Demo photography is exported from src/assets/images/index.ts as photos.*.
How to use images in blocks
1. Import metadata (not a public path string):
import { photos } from "../assets/images";
hero15: {
images: [
{ src: photos.karla, alt: "Portrait in soft light" },
{ src: photos.interior, alt: "Interior detail" },
],
}
2. Render with OptimizedImage:
---
import OptimizedImage from "@/components/elements/OptimizedImage.astro";
import { photos } from "@/assets/images";
---
<OptimizedImage
src={photos.karla}
alt="Portrait"
widths={[480, 768, 1024, 1440]}
sizes="(max-width: 1024px) 100vw, 50vw"
class="size-full object-cover"
loading="eager"
/>
OptimizedImage accepts:
ImageMetadatafromsrc/assets/→ optimized<Image />fromastro:assetsstringpaths (/images/logo/...) → plain<img>passthrough (SVGs / public)
Shared type: LocalImageSource in src/lib/image.ts.
Adding new photos
- Drop the file in
src/assets/images/ - Export it from
src/assets/images/index.ts - Reference
photos.yourKeyinblocks.tsor page props - Prefer
OptimizedImagein any new component that displays it
Do not put multi‑MB JPGs in public/ — they ship unprocessed.
What stays in public/
- Client / brand SVG logos
- Site chrome: favicon, OG image
Performance tips
- Default quality is
75onOptimizedImage(override per call) - Pass sensible
widths+sizesfor the layout (avatars ≠ hero full-bleed) loading="eager"only for LCP candidates; everything elselazy- Confirm the build log shows
/_astro/*.webpvariants