Back to Blog
Cloudflare R2Image OptimizationNext.js

Before Photos Reach the Site: Why I Needed an R2 Image Pipeline

The real requirement was not just uploading images. It was turning local originals into reliable web assets with sizes, URLs, metadata, and repeatable content data.

·1 min read

Yesterday I added a small photo pipeline for the gallery: source images go into photos/raw, scripts produce WebP variants, the assets are uploaded to Cloudflare R2, and YAML files are generated for content/gallery.

At first glance this sounds like "upload some photos." The actual requirement had three parts.

Originals Are Not Web Assets

Camera and phone originals are too large for direct page rendering. A single photo can be several megabytes, sometimes much more. Serving those files in a gallery would hurt first load, bandwidth, and mobile browsing.

So the originals stay out of the repository, and the public pages never point at them directly. The repo stores content metadata; R2 stores the actual image assets.

One Photo Has Multiple Jobs

The gallery has at least three viewing contexts:

  • The grid needs a small image that appears quickly.
  • The lightbox needs a balanced display image.
  • The original-view action needs a larger file with more detail.

That is why the script emits thumb.webp, display.webp, and full.webp. The three variants map to real user paths instead of treating every visitor as if they need the largest file immediately.

Content Data Should Be Repeatable

After upload, the site still needs title, dimensions, capture date, camera metadata, URLs, and a blur placeholder. Filling those fields by hand would be slow and fragile.

The processing script writes a manifest, and the generation step converts that manifest into YAML. The Next.js pages only read YAML; they do not need to know where the local file lived or how it reached R2.

Takeaway

The useful part of the pipeline is not saving one manual upload. It turns loose photo files into reliable web assets: sized, addressable, metadata-rich, and easy for the content system to consume again.