
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeI can see your issue! Looking at your code, you're destructuring body from the products object, but in your GROQ query, you're fetching the body field at the top level. However, the body field likely contains block content that references other documents or assets, and you need to expand those references in your query.
The most likely issue is that your body field contains block content that needs to be properly expanded. Try updating your query to this:
const query = groq`*[_type == "product" && slug.current == $slug][0]{
title,
image,
price,
body[]{
...,
markDefs[]{
...,
_type == "internalLink" => {
"slug": @.reference->slug
}
},
_type == "image" => {
...,
asset->
}
},
blurb,
"slug": slug.current,
defaultProductVariant
}`;The key change is body[]{...} which properly expands the array of block content. This syntax tells GROQ to expand each item in the body array, handle image assets (with asset->), and resolve any internal link references in markDefs.
A few other things to check:
Verify the data is actually there: Add a console.log(body) or console.log(products) right before your return statement to see if the body data is actually being fetched. If it's undefined or an empty array, that confirms the query issue.
Check your schema: Make sure your Product schema actually has a body field defined as an array of block content:
{
name: 'body',
type: 'array',
of: [{type: 'block'}]
}API version: If you're using a recent Sanity API version, be aware that the default perspective changed to published in API v2025-02-19. Make sure your product documents are actually published, not just drafts. You can test this by temporarily adding perspective: 'previewDrafts' to your client configuration.
Compare with your blog query: Since you mentioned this exact setup works for your blog, compare the GROQ queries between the two projects. The blog query likely has the proper expansion syntax (body[]{...}) that the product query is missing.
According to the Presenting Portable Text guide, when you have references to other documents (like images or internal links) in your Portable Text, you need to use GROQ's join syntax to properly fetch the referenced data. The body[]{...} syntax with asset dereferencing is essential for PortableText to render correctly.
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