Filter posts by tag "internship" in GROQ query
Looking at your code, I can see you want to filter posts by tags containing the string "internship". The key GROQ operator you need is the in operator to check if a value exists in an array.
Here's how to modify your query:
Basic filter for exact match:
sanityClient
.fetch(
`*[_type == "post" && "internship" in tags]{
title,
slug,
tags,
mainImage{
asset ->{
_id,
url,
alt,
}
}
}`
)This uses the in operator which checks if the string "internship" exists anywhere in your tags array.
For a button-triggered filter, add state management:
export default function AllPosts() {
const [allPostsData, setAllPosts] = useState(null);
const [showInternships, setShowInternships] = useState(false);
const position = useMousePosition();
const location = useLocation();
useEffect(() => {
// Build query based on filter state
const filter = showInternships
? `*[_type == "post" && "internship" in tags]`
: `*[_type == "post"]`;
sanityClient
.fetch(
`${filter}{
title,
slug,
tags,
mainImage{
asset ->{
_id,
url,
alt,
}
}
}`
)
.then((data) => setAllPosts(data))
.catch(console.error);
}, [showInternships]); // Re-fetch when filter changes
return (
<div className={styles.flex}>
<div className={styles.landingTitle}>
{position.x}:{position.y}
<h1 className={styles.verticalText}>Work</h1>
{/* Add filter button */}
<button onClick={() => setShowInternships(!showInternships)}>
{showInternships ? "Show All Posts" : "Show Internships Only"}
</button>
</div>
<div className={styles.wrapper}>
{allPostsData &&
allPostsData.map((post, index) => (
<Link to={'/' + post.slug.current} key={post.slug.current}>
<span>
<img className={styles.heroImage}
src={post.mainImage.asset.url}
alt={post.mainImage.alt}
/>
<h2 className={styles.title}>
{post.title}
</h2>
</span>
</Link>
))}
</div>
</div>
);
}Important notes:
- The
"internship" in tagssyntax checks if the exact string "internship" exists in your tags array - If your tags are objects (like
{title: "internship"}), you'd need:"internship" in tags[]->titleor similar depending on your schema - The
inoperator returnstruewhen it finds a match,falseif no match, andnullif the array contains null values
For partial matching (if you need to match tags that contain "internship" as part of a longer string), you'd use the match operator instead:
`*[_type == "post" && tags match "*internship*"]`This would match tags like "summer-internship", "internship-2024", etc.
Show original thread12 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.