a tool for shared writing and social publishing
0

Configure Feed

Select the types of activity you want to include in your feed.

fix: use resize=contain in supabase image loader to prevent crop (#301)

The crop in #286 was in the image *serving* path, not upload. The
next/image custom loader (supabase-image-loader.js) hit Supabase's
render/image endpoint without a resize param, so it defaulted to
resize=cover. Because next/image only passes `width` to a custom loader
(never height), imgproxy filled the missing height with the source
height and cropped the width to fit the box — chopping the right side
off large images.

Verified against the reported image on prod (5712x4284) and locally:
width=3840 -> cropped (full source height kept)
width=2500 -> still cropped (clamping width alone does not help)
width=3840&resize=contain -> correct aspect, no crop

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

authored by

Tyler Lawson
Claude Opus 4.8 (1M context)
and committed by
GitHub
(Jun 1, 2026, 11:23 AM EDT) 007c7a40 a365ceed

+5 -1
+5 -1
supabase/supabase-image-loader.js
··· 1 1 export default function supabaseLoader({ src, width, quality }) { 2 2 const path = src.startsWith("/") ? src.slice(1) : src; 3 - return `${process.env.NEXT_PUBLIC_SUPABASE_API_URL}/storage/v1/render/image/public/${path}?width=${width}&quality=${quality || 75}`; 3 + // resize=contain scales proportionally to fit `width`. Without it Supabase 4 + // defaults to resize=cover, and since next/image only passes width (no 5 + // height), imgproxy fills the missing height with the source height and crops 6 + // the width to fit — chopping the right side off large images. See #286. 7 + return `${process.env.NEXT_PUBLIC_SUPABASE_API_URL}/storage/v1/render/image/public/${path}?width=${width}&quality=${quality || 75}&resize=contain`; 4 8 }