Filter GROQ query by array of referenced category names
I can help you fix that GROQ query! The issue is with the syntax of your filter condition. You're close, but the way you're checking if dereferenced category titles match your array needs adjustment.
Here's the corrected version:
export const getPublishedBlogPosts = (
categories: Array<String>
) => `*[_type == "post" && published == true ${
categories.length > 0 ? `&& categories[]->title in [${categories.map(c => `"${c}"`).join(", ")}]` : ""
}] | order(updatedNewestFirst) {
categories[]-> {
title
},
author-> {
name,
title,
image,
slug,
},
type,
slug,
title,
description,
mainImage,
}`;The problems with your original query:
- The syntax
categories[]->title [@ in ${categories.join(", ")}]is malformed - You're not wrapping the string values in quotes - GROQ needs
["Freelance Writing"]not[Freelance Writing] - The
@operator isn't needed here for a simpleincheck
What the fix does:
categories[]->title- dereferences all category references in the array and gets theirtitlefieldin [...]- checks if any of those titles exist in your provided array${categories.map(c =>"${c}").join(", ")}- properly formats your JavaScript array into a GROQ array with quoted strings
So when you call:
posts: await sanity.fetch(getPublishedBlogPosts(["Freelance Writing"]))The resulting GROQ filter becomes:
&& categories[]->title in ["Freelance Writing"]This will match any post where at least one of its category references has a title of "Freelance Writing".
Alternative approach using count:
If you prefer being more explicit, you can also use:
const categoryFilter = categories.length > 0
? `&& count((categories[]->title)[@ in [${categories.map(c => `"${c}"`).join(", ")}]]) > 0`
: "";This filters the dereferenced titles to only those in your array, counts them, and checks if the count is greater than 0. Both approaches work, but the in operator is simpler and more readable.
Show original thread36 replies
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.