groqd icon indicating copy to clipboard operation
groqd copied to clipboard

Allow nullable assets in SanityImage

Open heggemsnes opened this issue 1 year ago • 4 comments

Sometimes in Sanity you can end up with an image field that exists, but the asset reference is deleted.

You can recreate this by creating an image field with additional fields such as caption, then filling out a caption and then removing the asset. In this case the q.sanityImage("figure") query fails since asset cannot be nullable.

Could be solved by passing a "nullableAsset" parameter to the function.

CleanShot 2023-03-30 at 13 04 12@2x

heggemsnes avatar Mar 30 '23 11:03 heggemsnes

Is there a workaround for this? I've just hit the same issue by defining an image as nullable, the error popped up after adding an image and then removing it.

Snippet from query: ogImage: sanityImage('ogImage').nullable()

Error: result.seo.ogImage.asset`: Expected object, received null

leighkendell avatar May 02 '23 08:05 leighkendell

No, we just created a custom query:

export const imageInnerQuery = {
  _ref: ["asset._ref", q.string().nullable()],
  caption: q.string().nullable(),
  alt: ["coalesce(alt, asset->altText)", q.string().nullable()],
  crop: q
    .object({
      top: q.number(),
      bottom: q.number(),
      left: q.number(),
      right: q.number(),
    })
    .nullable(),
  hotspot: q
    .object({
      x: q.number(),
      y: q.number(),
      height: q.number(),
      width: q.number(),
    })
    .nullable(),
  asset: q("asset")
    .deref()
    .grab({
      metadata: q("metadata").grab({
        dimensions: q.object({
          aspectRatio: q.number(),
          height: q.number(),
          width: q.number(),
        }),
        lqip: q.string(),
      }),
    })
    .nullable(),
} satisfies Selection

export const imageQuery = (fieldName: string) => {
  return q(fieldName).grab(imageInnerQuery).nullable()
}

heggemsnes avatar May 03 '23 09:05 heggemsnes

I've run into this too and am still pondering what the right solution might be.

In some sense, this error is actually pretty useful for notifying you of malformed content. I can't think of a scenario where you want an image to render when there's no src for that image. This can be nice to notify you of missing images in large content lakes that otherwise wouldn't have been noticeable. Think of an old blog post for an alternate language (in a lake of hundreds of blog posts) that has a broken image because someone deleted the image and didn't realize this blog post referenced it.

That being said, this error can be annoying to run into when content is still WIP.

Maybe a nullableAsset option might be the right move for this because it's easy to switch between the two scenarios mentioned above. Gonna keep thinking on it

maxyinger avatar Jul 05 '23 16:07 maxyinger

I can't think of a scenario where you want an image to render when there's no src for that image.

The snippet @leighkendell shared is a perfect example: an optional open graph image. Ran into the same issue in my project, where the SEO object fails validation when no open graph image is provided, even when defined as nullable. (We have a fallback image configured in the code, so an undefined image src is perfectly acceptable.)

This can be nice to notify you of missing images in large content lakes that otherwise wouldn't have been noticeable.

Agreed. If an image is defined as a required field, that's the desired functionality. But there should be an option to mark it as nullable, just like any other field type.

If the sanityImage function can't support nullable, then the separate nullableAsset option suggested sounds like a good approach.

acrobertson avatar Sep 15 '23 15:09 acrobertson