Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

next-sanity/image does not appear to be fully using hotspot #1647

Open
JamesSingleton opened this issue Aug 11, 2024 · 4 comments
Open

next-sanity/image does not appear to be fully using hotspot #1647

JamesSingleton opened this issue Aug 11, 2024 · 4 comments

Comments

@JamesSingleton
Copy link
Contributor

Is your feature request related to a problem? Please describe.
I had originally been using sanity-image which was good. However, after the livestream with Knut and Lee, I wanted to try using next/image with a loader for Sanity images. Digging through this repo I found that there was next-sanity/image. So I went to implement it as pretty much a drop in replacement for sanity-image. However, I noticed that sometimes it used the hotspot and sometimes it didn't

Describe the solution you'd like
It would be nice if I didn't have to crop and it could just use the hotspot.

Describe alternatives you've considered
Well as described above, I used sanity-image.

Additional context

An example where I needed to crop in order to get a hotspot

Before cropping my image BUT still have the hotspot
Screenshot 2024-08-11 at 3 19 18 PM

image

After cropping the image with same hotspot
Screenshot 2024-08-11 at 3 19 55 PM

Screenshot 2024-08-11 at 3 18 25 PM

An example where I didn't need to crop in order to get a hotspot

Screenshot 2024-08-11 at 3 25 26 PM

Image in the network tab
Screenshot 2024-08-11 at 3 25 37 PM

Display in a card element
Screenshot 2024-08-11 at 3 26 09 PM

How I am using the component

// components/image.tsx
import createImageUrlBuilder from '@sanity/image-url'
import { Image as SanityImage, type ImageProps } from 'next-sanity/image'

import { projectId, dataset } from '@/lib/sanity.api'

const imageBuilder = createImageUrlBuilder({
  projectId,
  dataset,
})

export const urlForImage = (source: Parameters<(typeof imageBuilder)['image']>[0]) =>
  imageBuilder.image(source)

export function Image(
  props: Omit<ImageProps, 'src' | 'alt'> & {
    src: {
      _key?: string | null
      _type?: 'image' | string
      asset: {
        _type: 'reference'
        _ref: string
      }
      crop: {
        top: number
        bottom: number
        left: number
        right: number
      } | null
      hotspot: {
        x: number
        y: number
        height: number
        width: number
      } | null
      caption?: string | undefined
    }
    alt?: string
  },
) {
  const { src, ...rest } = props
  const imageBuilder = urlForImage(props.src)
  if (props.width) {
    imageBuilder.width(typeof props.width === 'string' ? parseInt(props.width, 10) : props.width)
  }
  if (props.height) {
    imageBuilder.height(
      typeof props.height === 'string' ? parseInt(props.height, 10) : props.height,
    )
  }

  return (
    <SanityImage
      alt={typeof src.caption === 'string' ? src.caption : ''}
      {...rest}
      src={imageBuilder.url()}
    />
  )
}
@JamesSingleton
Copy link
Contributor Author

I guess this technically could have been a bug report as well but 🤷🏼‍♂️

@coreyward
Copy link

Any library using @sanity/image-url will be inaccurate so long as they ignore this 3.5 year old issue that I documented extensively and even built an entire interactive playground to demonstrate. Sanity doesn't seem to have any interest in fixing it. That is half the reason for why sanity-image exists and uses its own, leaner, more accurate and reliable URL builder.

@JamesSingleton
Copy link
Contributor Author

@coreyward does sanity-image expose a loader that can be used with next/image? I’m mainly doing some experimenting after the livestream with Lee and Knut.

@coreyward
Copy link

A loader is just a function that generates the URLs for your image. Since sanity-image exports both buildSrc and buildSrcSet functions that handle the vast majority of the optimizations performed by the library you can use them in a loader to produce more accurate, optimized image URLs.

This said, I don't believe Next provides you any way to pass the the hotspot and crop values to your loader. They don't even let you pass in the height of the image. It's a hyper-constrained, ridiculously convoluted system that treats devs with kid gloves, all for an exorbitant fee.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants