
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeLooking 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:
"internship" in tags syntax checks if the exact string "internship" exists in your tags array{title: "internship"}), you'd need: "internship" in tags[]->title or similar depending on your schemain operator returns true when it finds a match, false if no match, and null if the array contains null valuesFor 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.
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