How to output a rectangle image using the image client library in Sanity.io

9 replies
Last updated: Jul 22, 2021
Hey how do I always output a rectangle image using the image client library? I have pack shots of products that are always in a random size with a transparent background. I want the output image to be square though in a fixed size, where the product is fully visible. For some reason the image is always cropped, no matter what property I use for the “fit” parameter.
Original image:
https://cdn.sanity.io/images/mxqn1342/develop/cf033ca4c0dac8c511d2603912dc5bae94ab6008-1524x2200.png Output image using client library (
product.image.size(800, 800).fit('fillmax').auto('format').url()
): https://cdn.sanity.io/images/mxqn1342/develop/cf033ca4c0dac8c511d2603912dc5bae94ab6[…]0.png?rect=0,338,1524,1524&w=800&h=800&fit=fillmax&auto=format Output image using client library (
product.image.size(800, 800).fit('clip').auto('format').url()
): https://cdn.sanity.io/images/mxqn1342/develop/cf033ca4c0dac8c511d2603912dc5bae94ab6[…]2200.png?rect=0,338,1524,1524&w=800&h=800&fit=clip&auto=format
Any ideas?
AI Update

Looking at your URLs, I can see the issue - there's a rect=0,338,1524,1524 parameter being applied, which means Sanity is using the crop/hotspot data stored with your image document. This is overriding your fit parameter and causing the cropping you're seeing.

The solution is to use the ignoreImageParams() method in the image URL builder to tell Sanity to ignore any crop or hotspot data stored with the image:

product.image
  .ignoreImageParams()
  .size(800, 800)
  .fit('fillmax')
  .bg('transparent')
  .auto('format')
  .url()

The ignoreImageParams() method removes any stored crop/hotspot settings, so your fit parameter will actually work as intended.

For your use case with transparent product shots that need to remain fully visible in a square output, I'd recommend using fit('fillmax') combined with a transparent background:

product.image
  .ignoreImageParams()
  .size(800, 800)
  .fit('fillmax')
  .bg('transparent')
  .auto('format')
  .url()

Here's what the different fit modes do when you're not being overridden by crop data (from the image transformations documentation):

  • fillmax - Places the image within the box you specify, never scaling up. If there's excess room, it fills with the bg color (perfect for your use case!)
  • clip - Resizes to fit within bounds without cropping or distorting
  • fill - Like clip, but fills any free area with the bg color
  • max - Fits within the box but never scales up
  • min - Resizes and crops to match aspect ratio without exceeding original dimensions
  • crop - Crops the image to fill the size when both w and h are specified

For the transparent background padding, you can use bg('transparent') or specify a hex color like bg('ffffff') for white.

The key takeaway: Whenever you have existing crop/hotspot data on an image field but want to control the output differently, use ignoreImageParams() first in your chain to override the stored image parameters.

Hi Maarten, something like this should work -
fillmax
without the
rect
and with a
bg
specified to fill the excess space in the image: https://cdn.sanity.io/images/mxqn1342/develop/cf033ca4c0dac8c511d2603912dc5bae94ab6008-1524x2200.png?w=800&h=800&fit=fillmax&bg=ffff .
A follow-up question would be how to get rid of the
rect
in the URL in this case, other than simply appending the params to the raw image URL. Not sure - let's investigate 🙂
Yeah I noticed indeed that the rect is appended automatically when using the client lib. Might be related to this issue on Github, not sure: https://github.com/sanity-io/image-url/issues/32
Also, the correct way to specify a transparent background is by setting the bg to a ARGB value, right? Like so: 00FFFFFF
Hmmzz transparency seems not supported in this case either..
I mean the “original” image is already transparent which isn’t respected during transformation
Seems like it's adding a solid background even when using transparency indeed: https://cdn.sanity.io/images/mxqn1342/develop/cf033ca4c0dac8c511d2603912dc5bae94ab6008-1524x2200.png?w=800&h=800&fit=fillmax&bg=0fff I'll share with the team.
No the original image is transparent so I expect the transformed image to respect that transparency
https://codepen.io/mdings/pen/MWmeeZE
Oh, I see. So the padding is transparent but the base image isn't. Thanks for reporting
I've pushed a fix for this issue, and have scheduled a CDN invalidation of the cache - so this should eventually be fixed. You should be able to test it by using slightly different parameters or appending another query parameter
Thanks
user Z
! That seems to be working now

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?