This draft exists only to prove the image pipeline renders optimized output. The
feature image above (the post hero) and the listing-card cover both come from the
single co-located image in this bundle’s frontmatter.
Inline image
A local Markdown image flows through <MdImage> and comes out as a single-format
WebP <img> with a responsive srcset, lazy-loaded (below the fold).
Gallery grid
<GalleryImage> renders a <picture> with AVIF + WebP sources, lazy. No
route-level gallery surface exists yet (Lane C / R2 is deferred — see
docs/media_lane_c_r2_runbook.md); this MDX-authored grid is the lightweight
form for when a few images want a gallery layout inside a post.
That’s all four image kinds, each through the build-time compile lane.
Lane C — R2 gallery (out of git, ADR-0017)
Everything above is Lane A: editorial images that live in this post’s bundle
(in git) and are optimized at build. The tiles below are Lane C — their
originals live in the asset host (files.ngockhoi96.dev, an R2 bucket out of
git) and are resized on demand by Cloudflare Images transforms. Authored with the
r2("<key>") keyed reference, so <GalleryImage> emits a responsive <picture>
of /cdn-cgi/image/... URLs (AVIF + WebP, a width ladder), never a bare <img>.
These render only after R2 is provisioned (bucket + files.ngockhoi96.dev
custom domain + Transformations enabled + the sample images uploaded — see
docs/cloudflare/r2.md and docs/cloudflare/images.md). Until then they 404;
that’s expected for a dev fixture and never ships (draft: true).



Lane A vs Lane C, side by side: same <GalleryImage> component, two storage
origins, one routing rule (editorial → git/build; heavy → R2/transform).