How to Insert an Image into a Portable Text Block with Alt Text and Caption Predefined

31 replies
Last updated: Jul 14, 2020
Newbie Question: Is it possible to configure an image object in Sanity Studio so editors can select and insert an image into a portable text block as an inline image and have the alt text and caption predefined? The perfect scenario would be if the caption and alt text were set when the image is first uploaded, then editors have the ability to override the original values where required in subsequent uses of the image.
AI Update

Yes, it is possible to configure an image object in Sanity Studio so editors can insert images into portable text with predefined alt text and captions! Here's how this works:

Adding Custom Fields to Images

You can add custom fields like alt and caption directly to your image schema within the portable text block definition:

import {defineField, defineArrayMember} from 'sanity'

defineField({
  name: 'body',
  title: 'Body',
  type: 'array',
  of: [
    {type: 'block'},
    defineArrayMember({
      type: 'image',
      options: {
        hotspot: true
      },
      fields: [
        {
          name: 'alt',
          title: 'Alt Text',
          type: 'string',
          description: 'Important for SEO and accessibility'
        },
        {
          name: 'caption',
          title: 'Caption',
          type: 'string'
        }
      ]
    })
  ]
})

About Asset-Level Metadata

While Sanity's image asset documents store metadata like dimensions and color palette automatically, image assets themselves don't have built-in altText or caption fields. These fields need to be defined at the document level (as shown above).

Creating Inline Images

For truly inline images (appearing within the text flow rather than as separate blocks), you can create custom inline objects using the of property within your block definition:

defineArrayMember({
  type: 'block',
  of: [
    {
      type: 'image',
      name: 'inlineImage',
      title: 'Inline Image',
      options: {inline: true},
      fields: [
        {name: 'alt', type: 'string', title: 'Alt Text'},
        {name: 'caption', type: 'string', title: 'Caption'}
      ]
    }
  ]
})

The Inheritance Challenge

Your ideal scenario—setting alt text and caption when an image is first uploaded, then allowing overrides in subsequent uses—is not directly supported in Sanity's architecture. Here's why:

  • Image assets are stored separately from the documents that reference them
  • Each time you add an image to a document, you're creating a new reference with its own field values
  • There's no automatic inheritance from asset-level metadata to document-level fields

Workaround Options

  1. Use a media plugin like sanity-plugin-media to add custom metadata fields to your assets at upload time, though you'd still need to manually copy these values when inserting images

  2. Create a custom input component that automatically populates alt/caption fields from asset metadata (if you've stored it there) but allows editors to override it

  3. Use initial value templates to provide default values for these fields when images are added

The fields-on-image approach shown above is the standard pattern and gives you the flexibility you need, though it requires editors to fill in these fields each time they use an image.

i would say yes ... but i think it depends on what you mean by predefined
you can make an inline image component that can be inserted into portable text for sure, and you can add fields for alt and caption to that component.

you can also have initial values for new objects ... this is where i'm not 100% sure what you're asking

do you want to have all new images use a predefined value for alt and caption?

or just that you want the user to add those the first time the image is used?
I'm looking to try to recreate the way that WordPress handles media: the first time an image is uploaded, it's given a unique caption and alt text. When the image is subsequently inserted as an inline image, the caption and alt text are used, with the ability to change / override where required.
mmm, yeah
sanity definitely thinks about content, images included much differently than WP
because reusing an image doesn't bring along your alt and caption
Exactly
I wonder if there is a way to do it?
you'd almost need to create document type of Image
and then do a reference to that Image in your portable text
Is that possible?
but even that isn't the same
since its still only giving you the option of alt/caption usage a single time
so if you update alt/caption, it would be updated everywhere
That would still be better than what I have now!
well, then, yes... you could make a document type and create an object for your portable type to reference that document
Are there any docs on how I can add a reference to another document inside a portable text block?
not sure ... just seems doable in theory
you'd need to create an object component, with a reference inside of it, but that should be possible
actually, i've done something similar but with Videos
Thanks. I'm going to do some more research!
i have a Video document type where i add video with captions and other details
and then i reference that as an Insert for my body copy on articles
That sounds very close to what I'm after!
cool.. yeah the only "downside" i see is again that if you edit the content of your Image document, it will get updated anywhere that document is referenced
I can live with that
here's what my Body Copy in the Article looks like

{
      title: "Body Copy",
      name: "bodyCopy",
      type: "array",
      of: [{ type: "block" }, { type: "inlineImage" }, {type: "reference", to: {type: "video"}}]
    },
its the third item in the
of
reference to video
Gotcha. Thanks
user N
much appreciated!
yep! good luck... let me know if you have questions
I will. It's great to know that there is a helpful community here. I've been on a journey trying to find the best alterantive to WordPress and i think I may have found it!
same! i've been a WP developer for most of my career (and i still love it), but sometimes you just need more or something different ... and i've been loving sanity since finding it
It was Gutenberg that finally drove me away. I've tried ClassicPress which is okay but I found myself using it headless more and more. I'm in the process of settling on Sanity / Gatsby for clients who need a GUI and MDX / Gatsby for everyone else. Thanks again for your help! 😁

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?