Using referenced document preview values in parent object preview

8 replies
Last updated: Oct 18, 2022
Children preview value in the parent preview
Hi everyone!

I was wondering, can I somehow use the
preview value of the referenced document in the preview of the parent?
I have an array of objects, object has two fields - a reference to the other document and a boolean. I would like to use the default values from the reference preview for the parent (object) preview. I know that I can get some useful data in the
select
section but it seems I can only get data from the fields. Why I would like to use it? Previously, when I had an array of references Sanity was by default showing the icon connected with the referenced type. Now when I have the list of objects (with ref inside) I have the default icon everywhere.
Any help would be appreciated
🙂

Sanity version:
"@sanity/base": "^2.33.3",
AI Update

Yes, you can definitely use preview values from referenced documents in your parent object's preview! The key is using dot notation in the select object to access fields from the referenced document.

Here's how you can set up your array of objects to show the referenced document's preview data:

{
  name: 'myArray',
  type: 'array',
  of: [{
    type: 'object',
    fields: [
      {
        name: 'reference',
        type: 'reference',
        to: [{type: 'yourDocumentType'}]
      },
      {
        name: 'isActive',
        type: 'boolean'
      }
    ],
    preview: {
      select: {
        // Access fields from the referenced document using dot notation
        title: 'reference.title',
        media: 'reference.image',
        subtitle: 'reference.subtitle',
        isActive: 'isActive'
      },
      prepare({title, media, subtitle, isActive}) {
        return {
          title: title,
          subtitle: isActive ? `${subtitle || ''}` : subtitle,
          media: media
        }
      }
    }
  }]
}

The important part is using the dot notation like 'reference.title' in your select object. This pulls data directly from the referenced document. You can access any field from the referenced document this way, including its media/icon.

To get the icon from the referenced document type, you can reference the image field that's used in that document's preview. If the referenced document type has a custom icon defined in its schema, that won't automatically carry over, but you can conditionally set icons in your prepare function based on the reference type.

For your specific use case where you want to preserve the type-specific icons, you might also consider importing the icon from the referenced schema and using it as a fallback:

import { YourDocumentIcon } from './path-to-schema'

prepare({title, media, isActive}) {
  return {
    title: title,
    subtitle: isActive ? '✓ Active' : 'Inactive',
    media: media ?? YourDocumentIcon
  }
}

This approach gives you the same visual experience you had with direct references while maintaining your additional boolean field. You can read more about this in the preview configuration documentation and this guide on creating richer array item previews.

Show original thread
8 replies
Here is my current data structure:
Witam 🥕 !Yes it is possible and you need to project the
ref
into your
select
.example:

export default {
  name: 'movie',
  type: 'document',
  fields: [...],
  preview: {
    select: {
      title: 'title',
      director: 'director.name' // if the movie has a director, follow the relation and get the name
    },
    prepare(selection) {
      const {title, director} = selection
      return {
        title: title,
        subtitle: `Directed by: ${director ? director : 'unknown'}`
      }
    }
  }
}

👉 https://www.sanity.io/docs/previews-list-views#dcbbdb0ec3aa
Cześć
user J
,
Cześć
user J
!
from your example,
name
is one of the fields in the
director
document, right? What I want to achieve is to get the preview values from this ref. By the preview values, I mean for example an image if there is one, and if not an icon of this document. Screenshot below shows which icon I want to get 🙂:
And I want to get this icon to have:
Ah okay I did not see what you meant before!1. Small Tip:
icon: VideoIcon
is enough 🙂 no need to use an img component, we got’ya! 2. There are 2 approaches to get the icons but I would need your actual schemas (barebones but seeing what fields are there), if you want more help, than that:
Prepare and then
turnicate the 2 or more icon options or define them like that :
{
  name: 'ticket',
  type: 'document',
  fields: [...],
  preview: {
    select: {
      title: 'title',
      summary: 'summary',
      status: 'status',
    },
    prepare({ title, summary, status }) {
      const EMOJIS = {
        open: '🎫',
        resolved: '✅',
        cancelled: '🚫'
      }
      return {
        title: title,
        subtitle: summary,
        media: <span style={{fontSize: '1.5rem'}}>{status ? EMOJIS[status] : '🎫'}</span>
      }
    }
  }
}
Or write your own
preview component which then can be 💅 a lot through JSX or Sanity UI.
Thanks for your help 🙂, it seems that we need to implement the logic on our own. I hoped that we will be able to reuse the logic from the default Sanity preview (which matches the document with the most accurate media (either image if there is an image in the document, or icon). If we can't reuse it, we will try to do it differently.
Wonderful 🙂 You can also try to set media and icons for all doc and refs upstream from the video doc, which then could work

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?