
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeLooking at your question, you're trying to use GROQ's order() clause within Structure Builder's documentList() to sort child documents based on custom calculations (like math operations on nested color picker values). The key issue is that Structure Builder's filtering system has limitations.
The short answer: No, you cannot use GROQ's order() clause directly in Structure Builder filters. However, there are two viable approaches to achieve custom ordering:
defaultOrdering() with a pre-computed field (Recommended)The Structure Builder's defaultOrdering() method requires a field name string, not a GROQ expression. The solution is to compute your ordering value and store it as a field in your document:
// In your schema
{
name: 'computedOrderValue',
type: 'number',
hidden: true, // Hide from editors if it's just for ordering
// Calculate this value when the color picker changes
}Then use it in Structure Builder:
S.documentList()
.title('Ordered Projects')
.filter('_type == "myType"')
.defaultOrdering([
{field: 'computedOrderValue', direction: 'desc'}
])You can compute this field using:
If pre-computing isn't feasible, create a custom component that fetches and displays documents with full GROQ ordering:
S.listItem()
.title('Custom Ordered List')
.child(
S.component(({documentStore}) => {
const [docs, setDocs] = useState([])
useEffect(() => {
const query = `*[_type == "myType"] | order(
color.hsv.v * color.hsv.s desc
)`
documentStore.getClient().fetch(query)
.then(setDocs)
}, [])
return (
<div>
{docs.map(doc => (
<DocumentListItem key={doc._id} doc={doc} />
))}
</div>
)
})
)As noted in the Structure Builder reference, the filter() method "does not support joins, since they operate on individual documents, and will ignore order-clauses and projections." This is because Structure Builder uses realtime listeners that need to efficiently determine which documents match the filter as changes occur.
The defaultOrdering() method works differently—it tells the UI how to sort the already-filtered results, but it can only reference actual document fields, not computed expressions.
You mentioned getting "faceblind" with terms like list, listItem, listType, etc. Here's a quick breakdown:
list() - Creates a pane containing multiple itemslistItem() - A single clickable item within a listdocumentList() - A specialized list that shows documents matching a filterdocumentListItem() - A single item representing a documentThe Structure Builder reference has the full breakdown of each method.
Bottom line: Pre-compute your ordering value into a document field, then reference it in defaultOrdering(). This gives you the full power of custom calculations while working within Structure Builder's constraints.
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