Images: Local Variants, Public Files and R2
Feature

Images: Local Variants, Public Files and R2

Responsive AVIF and WebP variants for site images, and a media queue that uploads larger assets to Cloudflare R2 with metadata in D1.

Image pipeline with public files and Cloudflare R2

Images are usually the heaviest part of a page. AstroWEBTheme handles two kinds separately.

Site images: generated variants

Images in src/site/assets/images/ are converted at build time into AVIF and WebP at 380, 640 and 1280 pixel widths (images.mjs). ResponsiveImage picks the variant for the screen, sets dimensions to prevent layout shift, and loads the first image eagerly while the rest load lazily.

Media library: public and R2

Files placed in src/site/assets/public/ or src/site/assets/private/ form an incoming queue. The media sync:

  1. uploads each file to the matching Cloudflare R2 bucket,
  2. records its metadata and URL in D1 (media_assets),
  3. generates optimised variants for new images,
  4. archives the source under src/site/storage/.

Public files can be served from an R2 custom domain, which keeps large assets out of the Git repository and the deployment bundle. Private files stay in a private bucket.

pnpm media:sync:dry          # preview local queue
pnpm media:sync:remote:dry   # preview what would reach R2 and D1

Both commands are dry runs. Always check them before a remote sync.

Connecting media to content

content_media_relations links a media row to a content row, and hero_image_id connects a post to its hero image. See Live Content With D1 and R2.