GROQ query to find related posts by shared tags
Great question! Finding related posts by tags is a common pattern in blog setups. Here's how to approach this in GROQ when your tags are references:
Basic Approach - Matching Any Tag
If you want to find posts that share any tag with the current post, you can use this pattern:
*[
_type == "post"
&& _id == "your-post-id"
][0] {
_id,
title,
tags,
"related": *[
_type == "post"
&& _id != ^._id
&& count(tags[@._ref in ^.^.tags[]._ref]) > 0
]
}How It Works
The key technique here is using count(tags[@._ref in ^.^.tags[]._ref]) > 0 which:
tags[@._ref in ^.^.tags[]._ref]- Filters the related post's tags to only those whose_refappears in the parent post's tags arraycount(...) > 0- Checks if there's at least one matching tag^.^.tags[]._ref- The double^is needed because the array filtertags[query]creates its own closure, so you need to reference up two levels to get the parent post's tags_id != ^._id- Excludes the current post from results
For Multiple Posts at Once
If you're querying multiple posts and want related posts for each:
*[_type == "post"] {
title,
slug,
excerpt,
tags[]->{title},
"related": *[
_type == "post"
&& _id != ^._id
&& count(tags[@._ref in ^.^.tags[]._ref]) > 0
] {
title,
slug,
excerpt
}
}If Tags Are Simple Strings
If your tags field is just an array of strings (not references), the query is simpler:
*[_type == "post" && count(tags[@ in ["tag1", "tag2"]]) > 0]Testing Your Query
You can test and experiment with these queries live at groq.dev. The reference-based approach is more flexible since it lets you store additional metadata about tags (like descriptions, colors, etc.) in your tag documents.
This pattern is super useful for building "you might also like" sections or related content widgets on your blog posts!
Show original thread10 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.