How AI is powering better personalization in e-commerce [with Vercel]. Sign up now

imageUrlBuilder not respecting hotspot and crop values from Sanity Studio

3 repliesLast updated: Dec 1, 2025

Tough time with the imageUrlBuilder (@sanity/image-url). It works fine to retrieve the image and manipulate it (set width/height flipping it etc...) but does not respect the
hotspot
and
crop
values I set in the studio.I've seen that the way the imageUrlBuilder works it by passing a SanityImageSource, which simply has a reference to the image document stored in the studio. How is it supposed to retrieve hotspot and crop values?
AI Update

The issue you're experiencing is a common one! The @sanity/image-url builder does automatically respect hotspot and crop values, but you need to pass the full image object to it, not just the asset reference.

The Key: Pass the Entire Image Field

When you query your data, make sure you're passing the complete image field (which includes asset, crop, and hotspot) to the image builder:

// ❌ This won't work - only has asset reference
const imageUrl = urlFor(document.image.asset).url()

// ✅ This works - includes crop and hotspot data
const imageUrl = urlFor(document.image).url()

Your GROQ Query Needs All the Data

Make sure your GROQ query fetches the complete image object with crop and hotspot. According to the Sanity documentation on displaying images, your query should look like this:

*[_type == "person"] {
  name,
  image {
    asset->,
    crop,
    hotspot
  }
}

The builder expects this structure:

{
  asset: { _ref: "image-abc123...", _type: "reference" },
  crop: { top: 0, bottom: 0, left: 0, right: 0 },
  hotspot: { x: 0.5, y: 0.5, height: 0.3, width: 0.3 }
}

How the Image Builder Handles Hotspot/Crop

When you pass the complete image object to @sanity/image-url, the builder automatically includes the crop and hotspot data in the URL it generates. This data tells Sanity's image CDN how to intelligently crop and focus the image based on the focal point you set in the Studio.

The hotspot contains x and y coordinates (as values between 0 and 1) that represent the focal point as a percentage of the image dimensions. When the image is transformed, Sanity's CDN ensures this focal point remains visible.

Troubleshooting Steps

Alternative: Manual CSS Implementation

If you're still having issues with certain frontend frameworks (particularly Next.js), you can manually implement the hotspot using CSS object-position:

function getPositionFromHotspot(hotspot) {
  if (!hotspot || !hotspot.x || !hotspot.y) return "center";
  return `${hotspot.x * 100}% ${hotspot.y * 100}%`;
}

<img
  src={urlFor(image).url()}
  style={{ objectPosition: getPositionFromHotspot(image?.hotspot) }}
/>

The key takeaway is that @sanity/image-url automatically respects hotspot and crop when you pass the complete image object—you don't need to do anything special beyond ensuring your query includes all the necessary fields.

Show original thread
3 replies

Was this answer helpful?

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.

Related contributions