Skip to main content

September 7, 2026

Sanity Look pins on a Centra PDP cover crop

Editors pin Shop the Look dots on the full photo. A tall cover crop on the product page slides those dots off the garment unless you remap them once.

Sander Korf3 min read

A fashion storefront shows Shop the Look on Centra product detail pages. Shop the Look is an editorial module: a lifestyle photo with clickable hotspots, each hotspot linking to a purchasable SKU so the shopper can add pieces from the outfit. Editors author Look documents in Sanity with LookPins (x/y hotspots) and Centra product links on each pin. Soft CMS rule: one Look per display-item URI so merchandising does not stack competing outfits on the same SKU page. Dots that sat on the blazer in Studio floated beside the hem on the live 3:4 cover crop.

GROQ lookByDisplayUri fetches the Look for the current PDP URI. mapLookDocumentToView turns Sanity shapes into view models. Each pin hydrates with live product and quick-add data from Centra. The server function can sit behind 'use cache: remote' with a five-minute cache life so editorial churn does not hammer Sanity on every PDP view.

In the demo, switch Wide source vs Tall source. Raw CMS pins miss the garment on the 3:4 crop. Remapped pins land where the editor intended on the visible frame.

Compare

CMS hotspots vs object-cover crop

Editors mark pins on the full lifestyle frame. The PDP shows a 3:4 cover crop. Toggle aspect ratio and remapping to see dots drift or land on the garment.

Full image space (editor view)

3:4 cover crop (storefront)

Red dots use Sanity x/y directly on the crop. Primary dots run through resolveCoverPinPosition once when image aspect differs from 3/4.

Pins live in image space

UI stacks as SectionShopTheLook plus ShopTheLookProvider. State tracks lookIndex, activePinKey, sizeByPinKey, and sizeErrorByPinKey. Switching looks reseeds size selections and clears pin focus and errors so stale chip state from Look A does not leak into Look B.

Editors mark hotspots on the full uploaded image. The storefront renders that media in a 3:4 frame with object-cover. CSS crops what does not fit. Raw x/y from Sanity describe the uncropped bitmap. I dropped those coordinates straight onto the crop and the dots floated beside the blazer hem.

Editors pin on the photograph they uploaded, not on a 3:4 crop inside Studio. resolveCoverPinPosition remaps pin x/y when image aspect differs from 3/4. Wide frames lose left and right, tall frames lose top and bottom. One function at the boundary is where that remap lives.

One-size SKUs still need an honest pick

One-size SKUs need the same care. seedOneSizeSelections auto-picks the only available variant so Add all is not blocked by a fake size picker. If that lone variant is unavailable, it stays unseeded. I am not going to pretend the shopper picked a size that cannot ship.

I switched looks without reseeding once. Look B inherited Look A's size error, and Add all then submitted a size the new pin never showed. The provider has to clear pin focus and errors on look change. Hydration from Centra still happens after the remap. Pins that miss the garment never get a useful quick add, because the shopper is tapping empty crop.

Cache and chrome have limits

Five-minute 'use cache: remote' means a pin nudge in Sanity can lag on the PDP. That is the deal for not hammering GROQ on every view. The one-Look-per-URI rule is soft. Nothing in the mapper stops two Looks if an editor ignores it, and two Looks stack outfits. Remap only runs when aspect differs from 3/4, so a source that already matches the frame can keep raw x/y.

Stylist chrome dropped a signature webfont. StylistSignature is a fixed SVG path atom now. The CMS no longer wires stylistName into font loading, which saves a render-blocking face for a decorative flourish.

Raw x/y from Sanity describe the uncropped bitmap, and object-fit: cover lives in layout space. I remap once, then hydrate Centra products on coordinates that still sit on the garment.


Happy coding! Sander