
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeI can see your issue! You're hardcoding the category ID ("1b65f627-7d10-4a35-9062-41e9245ff272") in your GROQ query instead of using the dynamic _id from the fetched category. Here's how to fix it:
The Problem:
Your query fetches the category data first, but then uses a hardcoded ID in the subquery instead of referencing the current category's _id.
The Solution:
Use the ^ parent operator in GROQ to reference the parent document's _id in your subquery:
export async function getStaticProps({ params, preview = false }) {
const query = groq`
*[_type == "blogCategory" && slug.current == $slug][0]{
_id,
title,
description,
slug,
image,
"blogCategory": *[_type=='article' && references(^._id)]
}
`;
const queryParams = { slug: params.slug };
const data = await getClient(preview).fetch(query, queryParams);
return {
props: {
preview,
siteSettings: await fetchGlobalSettings(),
allCategories: await sanity.fetch(groq`
*[_type == "blogCategory" && !(_id in path('drafts.**'))] {...}
`),
data: {
page: data, // data is already a single item now
query,
queryParams,
},
},
};
}Key changes:
Added [0] after the first filter to get a single category document instead of an array (so you don't need filterDataToSingleItem)
Used references(^._id) instead of hardcoding the ID. The ^ operator references the parent document (the category), and references() checks if the article's blogCategories array contains a reference to that category's _id
Simplified the data structure since we're now returning a single object instead of an array
Alternative approach if you prefer using query parameters:
const query = groq`
*[_type == "blogCategory" && slug.current == $slug][0]{
_id,
title,
description,
slug,
image,
"blogCategory": *[_type=='article' && references($categoryId)]
}
`;
const category = await getClient(preview).fetch(
groq`*[_type == "blogCategory" && slug.current == $slug][0]._id`,
{ slug: params.slug }
);
const queryParams = { slug: params.slug, categoryId: category };
const data = await getClient(preview).fetch(query, queryParams);However, the first approach with ^._id is cleaner and requires only one query.
Update your component to handle the simplified data structure:
const BlogView = (props) => {
const { data, preview, siteSettings = {}, allCategories } = props;
const { data: previewData } = usePreviewSubscription(data?.query, {
params: data?.queryParams ?? {},
initialData: data?.page,
enabled: preview,
});
const page = previewData;
if (!page || !page.blogCategory) return null;
return (
<Layout siteSettingData={siteSettings}>
{page.blogCategory.map((item, i) => (
<BlogItem data={item} key={item._id || i} />
))}
</Layout>
);
};The references() function is the proper way to check if a document has a reference to another document in an array field. This will dynamically filter articles based on whichever category page you're viewing!
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