Troubleshooting reference fields in a Next.js Landing page template
The issue is that your GROQ query isn't properly dereferencing the features array. When you have references in Sanity, you need to explicitly expand them using the -> operator and specify which fields you want to retrieve.
Your current query has features without any projection, which returns just the reference objects (containing _ref, _type, _key) rather than the actual feature document data. That's why you're seeing empty divs - the array exists but doesn't contain the field data you need.
Here's the corrected query:
*[_id == "global-config"][0]{
frontpage -> {
...,
content[] {...},
features[] -> {
_id,
title,
_key,
// add any other fields from your Features document
}
}
}The key changes:
features[] ->- The[]tells GROQ this is an array, and->dereferences each reference in the array- Projection after
->- You need to specify which fields to pull from the referenced Feature documents
If your Features documents have more fields (like description, icon, etc.), add those to the projection as well.
In your React code, you should then be able to access the data like this:
{features && (
<ul>
{features.map(feature => (
<li key={feature._id}>
{feature.title}
</li>
))}
</ul>
)}Note: I changed the key from feature (the whole object) to feature._id since React keys should be strings/numbers, not objects. The _key field would also work if your reference array items have unique keys.
The projections documentation explains how to use the -> operator to follow references and shape the returned data. This is essential when working with Sanity's reference fields to ensure you're fetching the actual document content rather than just the reference metadata.
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.