
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeLooking at your query structure, I can see the issue - your projection is creating an array of objects with conditional keys, which makes accessing the data awkward. The good news is there are better ways to handle this in GROQ!
Your current query structure creates nested objects within an array:
descriptions[]{
_type == 'descriptionShortProduct' => { "shortDesc": description},
_type == 'descriptionShopify' => { "shopifyDesc": description }
}This gives you an array where each element is either {shopifyDesc: [...]} or {shortDesc: [...]}, making it hard to access the data you want.
coalesce() (Recommended)The cleanest approach is to use GROQ's coalesce() function, which returns the first non-null value from its arguments:
const queryString = `*[_id in ['${referenceArray.join("','")}']]{
...,
"description": coalesce(
descriptions[_type == 'descriptionShortProduct'][0].description,
descriptions[_type == 'descriptionShopify'][0].description
),
"productImage": images[0]-> {...}
}`;This gives you a single description field that automatically falls back from short description to Shopify description.
If you need access to both descriptions separately, filter the array to find specific types:
const queryString = `*[_id in ['${referenceArray.join("','")}']]{
...,
"shortDesc": descriptions[_type == 'descriptionShortProduct'][0].description,
"shopifyDesc": descriptions[_type == 'descriptionShopify'][0].description,
"productImage": images[0]-> {...}
}`;Then in your code:
const description = product.shortDesc || product.shopifyDesc;select() for More Complex LogicFor more complex conditional logic, you can use select():
const queryString = `*[_id in ['${referenceArray.join("','")}']]{
...,
"description": select(
count(descriptions[_type == 'descriptionShortProduct']) > 0 => descriptions[_type == 'descriptionShortProduct'][0].description,
descriptions[_type == 'descriptionShopify'][0].description
),
"productImage": images[0]-> {...}
}`;The coalesce() approach is usually the cleanest since it automatically handles null/undefined values and gives you exactly what you need - one description field with a fallback chain. This is much easier to work with than trying to navigate the nested array structure your current query produces!
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.
Content operations
Content backend


The only platform powering content operations
By Industry


Tecovas strengthens their customer connections
Build and Share

Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag store