
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeI understand the confusion with hotspot and crop data! The key thing to know is that when you query an image with hotspot/crop data, that data is automatically included in the image object, but how you use it depends on which tool you're working with.
Let me break down the most common scenarios:
When you use the image URL builder, the hotspot and crop data are automatically applied when you pass the entire image object to it:
import imageUrlBuilder from '@sanity/image-url'
const builder = imageUrlBuilder(sanityClient)
function urlFor(source) {
return builder.image(source) // Pass the whole image object
}
// In your GROQ query, just get the image field normally:
// *[_type == "post"][0].mainImage
const imageUrl = urlFor(image)
.width(400)
.height(300)
.url()The builder will automatically read the hotspot and crop properties from your image object and apply them to the transformations.
The most common mistake is only passing the asset reference instead of the entire image object. Make sure your GROQ query includes the full image field:
// ✅ Correct - gets the whole image object including hotspot/crop
*[_type == "post"][0]{
mainImage
}
// ❌ Wrong - only gets the asset reference
*[_type == "post"][0]{
"imageUrl": mainImage.asset->url
}If you're using frameworks like Next.js where the hotspot doesn't seem to work automatically (a common issue), you can manually apply the hotspot using CSS:
function getPositionFromHotspot(hotspot) {
if (!hotspot || !hotspot.x || !hotspot.y) return "center";
return `${hotspot.x * 100}% ${hotspot.y * 100}%`;
}
// Usage with Next.js Image
<Image
src={urlForImage(image).url()}
alt={image.alt}
fill
style={{
objectFit: 'cover',
objectPosition: getPositionFromHotspot(image?.hotspot)
}}
/>Make sure hotspot is enabled in your schema first:
{
name: 'mainImage',
type: 'image',
options: {
hotspot: true // This enables the hotspot feature
}
}When you query an image with hotspot, the data structure looks like this:
{
_type: 'image',
asset: { _ref: '...', _type: 'reference' },
hotspot: {
x: 0.5, // 0-1 (percentage from left)
y: 0.3, // 0-1 (percentage from top)
height: 0.4,
width: 0.4
},
crop: {
top: 0,
bottom: 0,
left: 0,
right: 0
}
}The most likely issue you're facing is either not passing the complete image object to the URL builder, or working with a frontend framework that needs the manual CSS approach. If you're using the image URL builder correctly with the full image object, the hotspot should work automatically without any extra code!
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.
Content operations
Content backend


The only platform powering content operations
By Industry


Tecovas strengthens their customer connections
Build and Share

Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag store