Author schema preview shows undefined jobTitle after Sanity update

5 replies
Last updated: Jan 28, 2026
Hi, After updating sanity to latest versions my schema (author) preview doesn't work anymore. the jobTitle comes back as undefined. Has anyone else encountered this problem after update?Here is my Authors.js code .

import { FiUser } from 'react-icons/fi'

import { createHeading, formatDate } from '../../helpers'

import SlugInput from 'sanity-plugin-better-slug'

import { isUniqueAcrossAllDocuments } from '../functions/isUniqueAcrossAllDocuments'

export default {
   name: 'author',
   title: 'Author',
   type: 'document',
   icon: FiUser,
   fields: [
      {
         name: 'name',
         title: 'Name',
         type: 'string'
      },
      {
         name: 'slug',
         title: 'Slug',
         type: 'slug',
         inputComponent: SlugInput,
         validation: (Rule) => Rule.required(),
         options: {
            source: 'name',
            maxLength: 100,
            basePath: '<http://localhost.com|localhost.com>',
            isUnique: isUniqueAcrossAllDocuments,
            slugify: (input) =>
               input.toLowerCase().replace(/\s+/g, '-').slice(0, 100)
         }
      },
      {
         title: 'Job title',
         name: 'jobTitle',
         type: 'string',
         validation: (Rule) =>
            Rule.required().error('This is required dear friend!'),
         options: {
            list: [
               // Others
               { title: 'Managing Partner', value: 'Managing Partner' },
               { title: 'Account Director', value: 'Account Director' },
               { title: 'Creative Director', value: 'Creative Director' },
               { title: 'Concepter', value: 'Concepter' },
               { title: 'Finance', value: 'Finance' },
               { title: 'Producer', value: 'Producer' },
               { title: 'Storyteller', value: 'Storyteller' },

               // Developers
               { title: 'Lead Developer', value: 'Lead Developer' },
               { title: 'Senior Developer', value: 'Senior Developer' },
               { title: 'Medior Developer', value: 'Medior Developer' },
               { title: 'Junior Developer', value: 'Junior Developer' },

               // Designers
               { title: 'Lead Designer', value: 'Lead Designer' },
               { title: 'Senior Designer', value: 'Senior Designer' },
               { title: 'Medior Designer', value: 'Medior Designer' },
               { title: 'Junior Designer', value: 'Junior Designer' },
               { title: 'Junior Creative', value: 'Junior Creative' }
            ]
         }
      },

      {
         name: 'bio',
         title: 'Bio',
         type: 'blockContent'
      },
      {
         name: 'authorImage',
         title: 'Author image',
         type: 'imageWithAltText'
      }
   ],

   preview: {
      select: {
         title: 'name',
         jobTitle: 'jobTitle',
         media: 'authorImage'
      },
      prepare(selection) {
         const { title, jobTitle } = selection

         return Object.assign({}, selection, {
            title: title,
            subtitle: jobTitle
         })
      }
   }
}
AI Update

I can see your issue! This is a common problem when migrating to Sanity Studio v3. The issue is related to how fields with options.list are handled in preview configurations.

The Problem

When you have a string field with options.list (like your jobTitle field), there's a specific behavior in how the preview select works. According to the Sanity documentation on previewing from predefined string lists, when you use a prepare() function with fields that have predefined lists, Sanity passes the value (not the title) to the prepare() function.

However, if you're seeing undefined, it's likely because of how you're handling the selection in your prepare() function.

Solutions to Try

Solution 1: Simplify your preview (recommended)

Your prepare() function is unnecessarily complex. Try this simpler version:

preview: {
  select: {
    title: 'name',
    subtitle: 'jobTitle',
    media: 'authorImage'
  }
}

Remove the prepare() function entirely. Sanity will automatically handle the display correctly, showing the title from your options list.

Solution 2: If you need the prepare function

If the simplified version doesn't work, add some debugging:

preview: {
  select: {
    title: 'name',
    jobTitle: 'jobTitle',
    media: 'authorImage'
  },
  prepare(selection) {
    console.log('Preview selection:', selection)
    const { title, jobTitle, media } = selection

    return {
      title: title,
      subtitle: jobTitle,
      media: media
    }
  }
}

The Object.assign() you're using is redundant and could be causing issues.

Solution 3: Handle existing documents

If you have existing author documents created before the update, they might need to be re-saved:

  1. Open an existing author document in Studio
  2. Make a small change (or just click save without changes)
  3. Save it

This forces Sanity to re-process the document with the current schema.

Solution 4: Update for Studio v3 compatibility

Also note that in Studio v3, the inputComponent property has been renamed. Your slug field should use:

{
  name: 'slug',
  title: 'Slug',
  type: 'slug',
  components: {
    input: SlugInput  // changed from inputComponent
  },
  // ... rest of options
}

Make sure your sanity-plugin-better-slug is updated to a v3-compatible version.

Why This Happens

The preview system in Studio v3 has stricter handling of field selections. When you use Object.assign({}, selection, {...}), it can sometimes interfere with how Sanity internally processes the preview values, especially for fields with predefined lists.

Try Solution 1 first—removing the prepare() function entirely should resolve your issue in most cases. The jobTitle value will display correctly as the subtitle without any custom logic needed.

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