
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeI can help you filter out already-referenced sections from your reference field! The issue with your current query is the syntax - you're trying to access the parent document's array, but the approach needs adjustment.
Here's the corrected solution:
{
name: 'section',
title: 'Section',
type: 'reference',
to: { type: 'section' },
options: {
filter: ({ document }) => {
// Get all section IDs already referenced in the primary array
const referencedIds = document.primary
?.map(item => item.section?._ref)
.filter(Boolean) || []
return {
filter: '!(_id in $referencedIds)',
params: {
referencedIds
}
}
}
}
}What's happening here:
Extract referenced IDs in JavaScript: Instead of trying to do this purely in GROQ, we extract the _ref values from the primary array items in the filter function itself. This is more reliable since you have direct access to the document object.
Simple GROQ filter: The GROQ filter !(_id in $referencedIds) checks if the current section's _id is NOT in the array of already-referenced IDs.
Pass as params: We pass the array of IDs as a parameter to the GROQ query.
Important note: The filter function re-runs when the document changes, so as you add sections to your primary array, they'll automatically disappear from the available options in other items.
Making it reusable:
You can extract this into a utility function to keep your code DRY, as shown in this community example:
// utils/getFilter.js
export const getFilter = (document, field, refField = '_ref') => {
const existingEntries = document[field]
?.map(item => item[refField])
.filter(Boolean) || []
return {
filter: '!(_id in $existingEntries)',
params: {
existingEntries
}
}
}
// Then in your schema:
options: {
filter: ({ document }) => {
const referencedIds = document.primary
?.map(item => item.section?._ref)
.filter(Boolean) || []
return {
filter: '!(_id in $referencedIds)',
params: { referencedIds }
}
}
}This is a common pattern when building navigation menus, related content pickers, or any scenario where you want to avoid duplicate references in an array!
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