How to display the parent's label in a preview in Sanity.io

18 replies
Last updated: May 28, 2020
AI Update

This is a great question about customizing reference field previews in Sanity Studio! When you're selecting a reference, you can show additional data beyond just the title by configuring the preview property in your schema.

The key is using the select and prepare functions in the referenced document's schema (not the field that references it). Here's how:

Basic Example

// In your author.js schema (the document being referenced)
export default {
  name: 'author',
  type: 'document',
  fields: [
    {name: 'name', type: 'string'},
    {name: 'email', type: 'string'},
    {name: 'bio', type: 'text'}
  ],
  preview: {
    select: {
      title: 'name',
      subtitle: 'email'  // This shows up under the name!
    }
  }
}

Now when you select this author in a reference field, you'll see the name as the main text and the email underneath.

More Advanced with prepare()

You can use the prepare function to customize the display further:

preview: {
  select: {
    name: 'name',
    email: 'email',
    published: 'publishedPosts'
  },
  prepare({name, email, published}) {
    return {
      title: name,
      subtitle: `${email}${published || 0} posts`
    }
  }
}

Showing Referenced Data

You can even pull in data from nested references using dot notation:

preview: {
  select: {
    title: 'title',
    authorName: 'author.name',  // Access referenced author's name
    categoryTitle: 'category.title'
  },
  prepare({title, authorName, categoryTitle}) {
    return {
      title: title,
      subtitle: `by ${authorName} in ${categoryTitle}`
    }
  }
}

The preview configuration lives in the schema of the document type being referenced, and it automatically applies wherever that document is shown - in lists, reference selectors, and search results. Check out the preview configuration documentation for more details and examples!

user B
Thanks, but this does not work for references.
export default {
  title: 'Subcategory',
  name: 'subcategory',
  type: 'document',
  fields: [
    {
      title: 'Label',
      name: 'label',
      type: 'string',
    },
    {
      title: 'Parent category',
      name: 'parent',
      type: 'reference',
      to: [{ type: 'category' }],
    },
    {
      title: 'Position',
      name: 'position',
      type: 'number',
    },
  ],
  preview: {
    select: {
      title: 'label',
      subtitle: 'parent',
    },
  },
}
The
subtitle
could only be
parent._ref
which is not helpful information to the user. Is it possible to see the parent’s label?
I talked with
user M
about this, and he had this suggestion for the filter:
{
  title: 'Subcategory',
  name: 'subcategory',
  type: 'reference',
  to: { type: 'subcategory' },
  options: {
    filter: ({ document }) => {
      if (!document.category) {
        return
      }
      return {
        filter: 'parent._ref == $category',
        params: {
          category: document.category._ref
        }
      }
    }
  }
},

Oh, sorry. Didn't read your question properly there. 🙂
And, this for the preview:
...,
preview: {
  select: {
    title: 'name',
    subtitle: 'slug.current',
    media: 'image'
  }
}

Hey Ben, great to have you here 👋 For the preview question - assuming
parent
has a field called
label
, try using
subtitle: 'parent.label'
instead.
The
subtitle
could only be
parent._ref
which is not helpful information to the user. Is it possible to see the parent’s label?
Hey Ben, great to have you here 👋 For the preview question - assuming
parent
has a field called
label
, try using
subtitle: 'parent.label'
instead.
Ah – let me try that. It failed when I put
subtitle: 'parent'
which it should as parent is an object. But the console showed
parent
as being an object with just a
_ref
and
_id
property. Will try now
I talked with
user M
about this, and he had this suggestion for the filter:
{
  title: 'Subcategory',
  name: 'subcategory',
  type: 'reference',
  to: { type: 'subcategory' },
  options: {
    filter: ({ document }) => {
      if (!document.category) {
        return
      }
      return {
        filter: 'parent._ref == $category',
        params: {
          category: document.category._ref
        }
      }
    }
  }
},

Oh, sorry. Didn't read your question properly there. 🙂
Knut Melvær
user M
The filter works great, wasn’t sure what I could/could not query in the GROQ filter but the
._ref
works, cheers
And, this for the preview:
...,
preview: {
  select: {
    title: 'name',
    subtitle: 'slug.current',
    media: 'image'
  }
}

Now lets try the previews
That works too! Thanks so much guys, I joked on twitter that I wouldn’t get a response, but you guys have been awesome and so fast!
We're at least trying 😅

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?