Fetching multiple document types with conditional fields in Sanity GROQ query

7 replies
Last updated: Nov 29, 2025
Hello, I am using NextJS with Sanity and trying to fetch data of more than one document type to render on a page. I’m trying to use the below query but at the moment it is not working. Specifically I have a page on my website for events, and on that page I want to fetch ‘calendar’ documents, ‘notice’ documents, and ‘event’ documents.
*[_type in ['event', 'calendar', 'notice']]{
_type == 'event': {
  eventTitle,
  eventDate,
  venue,
  mainImage,
  artists[]->,
},
_type == 'notice': {
  _id,
  title,
  body, 
},
_type == 'calendar': {
  _id,
  month,
  'event': event[]->{
  title[],
  date,
  },
},
}
Grateful for any tips!
🙏
AI Update

I can see the issue with your query! The syntax you're using isn't quite right for conditional projections in GROQ. You're trying to use _type == 'event': { ... } as if it's creating conditional objects, but that's not valid GROQ syntax.

Here's the correct approach using conditional projections with the => operator:

*[_type in ['event', 'calendar', 'notice']]{
  _type,
  _type == 'event' => {
    eventTitle,
    eventDate,
    venue,
    mainImage,
    artists[]->
  },
  _type == 'notice' => {
    _id,
    title,
    body
  },
  _type == 'calendar' => {
    _id,
    month,
    'event': event[]->{
      title,
      date
    }
  }
}

Key differences:

  1. Use => instead of : - The arrow operator (=>) is what makes conditional projections work in GROQ
  2. Include _type in the base projection - This helps you identify which type each document is when you process the results in Next.js
  3. Remove the curly braces around conditions - Each condition should be at the projection level, not wrapped in an object

The way this works: when _type == 'event' is true, those fields get included in the projection. When it's false, they're simply omitted. Each document in your results will only have the fields relevant to its type.

If you want to include common fields for all types plus type-specific ones, you can use the ellipsis operator:

*[_type in ['event', 'calendar', 'notice']]{
  ...,
  _type == 'event' => {
    artists[]->
  }
}

This would include all existing fields from each document, plus expand the artists reference only for event documents. The ellipsis (...) is always evaluated first regardless of position, so it won't override your conditional fields.

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