Filtering for unique data in a query and handling duplicate categories in Sanity.io.
I need to correct my previous answer - GROQ does not have a built-in unique() function. I apologize for the misinformation.
Unfortunately, GROQ doesn't provide a native way to deduplicate results directly in the query. This means you'll need to handle uniqueness differently depending on your needs:
Option 1: Frontend Deduplication (Recommended for Your Use Case)
Since you're retrieving just titles, the most straightforward approach is to deduplicate in your application code:
const titles = await client.fetch(`*[_type == "yourDocumentType"].title`)
const uniqueTitles = [...new Set(titles)]While this means transferring duplicate data over the network, it's simple, reliable, and performant for most use cases.
Option 2: Prevent Duplicates at the Source
If duplicate titles shouldn't exist in the first place, consider using field validation in your schema to enforce uniqueness:
{
name: 'title',
type: 'string',
validation: Rule => Rule.custom(async (value, context) => {
const {document, getClient} = context
const client = getClient({apiVersion: '2023-01-01'})
const id = document._id.replace(/^drafts\./, '')
const duplicate = await client.fetch(
`*[_type == $type && title == $title && !(_id in [$id, $draftId])][0]`,
{
type: document._type,
title: value,
id,
draftId: `drafts.${id}`
}
)
return duplicate ? 'Title must be unique' : true
})
}This prevents duplicate titles from being created in the first place.
Option 3: Restructure Your Content Model
If certain titles represent reusable concepts, consider creating a separate document type for them that other documents reference. This naturally enforces uniqueness and creates a single source of truth.
Why No unique() in GROQ?
GROQ is designed as a query language focused on filtering, projecting, and ordering content from the Content Lake. Set operations like deduplication are typically handled at the application layer, giving you more control over which duplicate to keep and how to handle edge cases.
Bottom line: For your specific use case of retrieving unique titles, frontend deduplication is the most practical approach. It's simple and works well. If you need to prevent duplicates altogether, add validation to your schema instead.
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.