How to add images to Portable Text / Block Content in Sanity?

30 replies
Last updated: Jan 28, 2026
Hello, I have a question about the blockContent-schema + PortableText/React plugin. I build small sites for small businesses, often creative people who wants to custom their’ content a lot. As of now I use the portable text module as often as I can, as they can add/remove content as they wish, without me having to edit the studio. A little like other cmses like hubspot where the rich text-module allows the client to add pretty much anything.BUT, I’m wondering about images. Is there any addon or alternative to the blockContent that allows for the user to add images? Or can you add some functionality to the blockContent so they can add images into it? Thanks in advance!
☀️
AI Update

Yes! You can absolutely add images to Portable Text (block content) in Sanity. Images are one of the most common custom blocks people add, and it's actually quite straightforward to set up.

Adding Images to Block Content

To enable images in your Portable Text schema, you need to add the image type to the of array in your block content field. Here's how:

import { defineType, defineField } from 'sanity'

export default defineType({
  name: 'myDocument',
  type: 'document',
  fields: [
    defineField({
      name: 'content',
      type: 'array',
      of: [
        {
          type: 'block' // Standard rich text
        },
        {
          type: 'image', // This adds image blocks!
          fields: [
            {
              name: 'alt',
              type: 'string',
              title: 'Alternative text',
              description: 'Important for SEO and accessibility',
              options: {
                isHighlighted: true // Shows the field prominently
              }
            },
            {
              name: 'caption',
              type: 'string',
              title: 'Caption'
            }
          ]
        }
      ]
    })
  ]
})

What This Gives Your Clients

Once you add this, your clients will see an image icon in the Portable Text toolbar. They can click it to upload images directly into their content, just like they would in other rich text editors. The images appear as blocks within the content flow, and clients can add alt text and captions right there.

Rendering Images on the Frontend

When you query this content, you'll need to handle the image blocks in your frontend. Here's an example using React with @portabletext/react:

import { PortableText } from '@portabletext/react'
import { urlForImage } from '@/lib/sanity.image'
import Image from 'next/image'

const components = {
  types: {
    image: ({value}) => {
      const imageUrl = urlForImage(value.asset).url()
      
      return (
        <figure>
          <Image
            src={imageUrl}
            alt={value.alt || 'Image'}
            width={800}
            height={600}
          />
          {value.caption && <figcaption>{value.caption}</figcaption>}
        </figure>
      )
    }
  }
}

export default function MyComponent({ content }) {
  return <PortableText value={content} components={components} />
}

Additional Customization

You can also add:

  • Hotspot/crop data (built into Sanity's image type)
  • Multiple image fields (like thumbnails)
  • Custom validation (file size, dimensions)
  • Image metadata (photographer credits, licensing info)

This approach gives your clients the flexibility to add images wherever they need them in their content, without you having to create specific image fields for every possible location. It's perfect for blog posts, articles, case studies, and any content where images need to flow naturally with text.

For more advanced customization, including custom renderers in the Studio and handling complex image blocks, check out the Sanity guide on customizing Portable Text from schema to React component. It walks through everything from schema setup to frontend rendering with detailed examples!

Show original thread
30 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?