Images not rendering in markdown/blockcontent with materialization error

65 replies
Last updated: Jan 28, 2026
Hey all, I'm having a hard time making the images from my markdown/blockcontent render. I'm getting the following error (see screenshot). I'll attach snippets of my groq query and schema as well. Any guidance would be very helpful, I visited the Sanity "Block content image materializing" docs page but I'm still confused about how to integrate this properly.
Thanks in advance!
AI Update

I can help you with this! The issue you're running into is a common one when working with images in Portable Text/Block Content. Without seeing your screenshot, I'm guessing you're getting an error about missing image data or undefined asset references.

The core problem is that when you query Block Content with images, you need to explicitly dereference the image asset in your GROQ query. By default, image references in Block Content are just references (like {_type: 'image', asset: {_ref: 'image-abc123-...'}}) - they don't include the actual image URL or metadata.

The Solution: Use the -> Dereference Operator

In your GROQ query, you need to expand the asset reference using the dereference operator (->). Here's the pattern:

*[_type == "yourDocumentType"] {
  _id,
  title,
  body[]{
    ...,
    _type == "image" => {
      ...,
      asset->
    }
  }
}

The key part is asset-> which tells GROQ to fetch the full asset document instead of just the reference.

More Complete Example

If you're also using custom marks or annotations, you might need something like this:

*[_type == "post"] {
  _id,
  title,
  body[]{
    ...,
    _type == "image" => {
      ...,
      asset->{
        _id,
        url,
        metadata {
          lqip,
          dimensions
        }
      }
    },
    markDefs[]{
      ...,
      _type == "internalLink" => {
        "slug": @.reference->slug.current
      }
    }
  }
}

Schema Side

Make sure your schema includes the image type properly:

defineField({
  name: 'body',
  type: 'array',
  of: [
    {
      type: 'block'
    },
    {
      type: 'image',
      fields: [
        {
          name: 'alt',
          type: 'string',
          title: 'Alternative text'
        }
      ]
    }
  ]
})

When Rendering

When you render the Portable Text on the frontend, make sure you have a custom serializer for images. The exact implementation depends on your framework, but here's a general pattern:

// Example with @portabletext/react
import {PortableText} from '@portabletext/react'
import imageUrlBuilder from '@sanity/image-url'

const builder = imageUrlBuilder(client)

const components = {
  types: {
    image: ({value}) => (
      <img
        src={builder.image(value).width(800).url()}
        alt={value.alt || ''}
      />
    ),
  },
}

// Then use it
<PortableText value={body} components={components} />

The important thing is that once you've properly dereferenced the asset in your GROQ query with asset->, you'll have access to the full asset object with its URL and metadata, which you can then pass to Sanity's image URL builder or use directly.

Let me know if you're still stuck after trying the asset-> dereference - if you can share more details about the specific error message, I can help troubleshoot further!

Show original thread
65 replies

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.

Was this answer helpful?