Displaying unpublished referenced documents in Sanity's desk structure
The issue you're experiencing is related to how Sanity's references() function works with draft documents. When you use references() in a GROQ query, it checks the actual reference values stored in your documents. The problem is that draft documents have IDs prefixed with drafts., but references in your documents typically store the "clean" ID without this prefix.
When a product exists only as a draft (not yet published), its ID is something like drafts.product-123, but your productModel document likely stores the reference as just product-123. This mismatch causes the references() check to fail.
The recommended solution is to modify your filter to account for both the published ID and the draft ID version:
S.listItem()
.title('Models')
.icon(RocketIcon)
.child(
S.documentList()
.apiVersion('v2023-11-17')
.title('Models')
.filter(
'_type == "productModel" && references(*[_type=="product" && productType == "series" && !(_id in path("drafts.**"))]._id) || references(*[_type=="product" && productType == "series" && _id in path("drafts.**")]._id)'
)
)However, there's a simpler approach that often works better: modify your inner query to explicitly include both the published and draft IDs by using string replacement:
S.listItem()
.title('Models')
.icon(RocketIcon)
.child(
S.documentList()
.apiVersion('v2023-11-17')
.title('Models')
.filter(
'_type == "productModel" && (
references(*[_type=="product" && productType == "series"]._id) ||
references(*[_type=="product" && productType == "series"].{"draftId": "drafts." + _id}.draftId)
)'
)
)This approach checks if your productModel references either:
- The published product ID
- The draft product ID (constructed by adding the
drafts.prefix)
Why this happens: Perspectives in Sanity control which document versions you see. By default, queries return documents based on the published perspective, but when working in the Studio, you're often dealing with a mix of draft and published content. The references() function performs a literal ID match, so it needs to check against the actual IDs that exist in the Content Lake.
This solution ensures your productModel documents appear in the list regardless of whether the referenced product is published or still in draft state, which is typically the desired behavior when working in the Studio editing environment.
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.