😎 Discover cool tips and tricks for customization in our next Developer Deep Dive virtual event - sign up now!

Can you run GROQ inside a Document Preview?

6 replies
Last updated: May 12, 2022
Hi all, anyone ever run some groq inside a document preview? Inside a reference field I need to add a flag to illustrate whether the referenced document also references the current document πŸ™ƒ.

preview: {
    select: {
      title: 'title',
      subtitle: 'type',
      type: 'type',
    },
    prepare({ title = 'Untitled', type, subtitle }) {
      const sub = // groq - does this doc reference the parent doc?;
      return {
        title,
        subtitle: sub,
        media: eosIcon,
      };
    },
  },
May 11, 2022, 4:47 PM
Alternative is creating a custom component. Although achievable its a lot of work for such a small tweak to the default
array
of
references
setup... if I could somehow add the flag to the preview then I can save having to re-invent the wheel!
Any ideas/approaches/help more than welcome, thanks!
May 11, 2022, 4:49 PM
Hey Mark! Previews can't handle async functions, so you won't be able to fetch anything from there. Is the parent referenced on the document? If so, you can select a value from that document using this method.
May 11, 2022, 6:21 PM
user M
- thank you soooo much for the pointers there, as ever amazing support!
I am so close to having it work perfectly, but, there is potentially one fatal issue.

Working code and how it renders attached... all perfect.

preview: {
    select: {
      title: 'title',
      subtitle: 'type',
      type: 'type',
      ref: 'relEos.0.relEos',
      id: '_id',
    },
    prepare({ title = 'Untitled', type, subtitle, ref, id }) {

      const references = ref ? ref : {};
      let bidirectional = false
      let refIds;
      if(!isEmpty(references)) {
        refIds = Object.entries(references).map(([key, value]) => value?._ref);
        bidirectional = refIds.includes(id);
      }

      return {
        title,
        subtitle: bidirectional ? `${subtitle.toUpperCase()} - Bidirectional` : subtitle.toUpperCase(),
      };
    },
  }
The issue is I need this for every item in the reference array... obviously by using
ref: 'relEos.0.relEos'
in the select I'm limited to the first array item.
Doing
ref: 'relEos'
returns an array of all the references but I can't then access the data in those referenced documents without groq.
So hacky pirate me is thinking I can just add 30
ref: 'relEos.0.relEos'
to my
select
and then just conditionally process them.
Sensible good dev me is thinking it does indeed require a custom component. I've had a little poke through the source code for the
reference
field and am thinking I could piece together a custom reference component along the lines of this . I've not done much with `part:`'s before. Thoughts or ideas very much appreciated 😊.
May 12, 2022, 10:39 AM
Ah, yeah that is an issue. I think at this point you will need to create a custom preview component, since it'll allow you to create a React component that can handle promises.
May 12, 2022, 5:46 PM
You can make custom preview components?! I love Sanity! Thanks for the direction you utter champion 🀘
May 12, 2022, 6:34 PM
Haha, you're welcome! It's a really similar process to creating a custom input component. More on it here .
May 12, 2022, 6:36 PM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?