Help with outputting background image from Sanity in Next.js project
Looking at your code, I can spot the issue! In your GROQ query, you're correctly fetching the image data with personReference->{image{asset->{url,_id}}}, but when you're mapping over the collaborators in your <ProjectCard /> component, you're not accessing the nested structure properly.
The problem is here:
{collaborators.map((props) => (
<Avatar key={props._id} url={props.url} />
))}Your query returns collaborators with a structure like:
{
personReference: {
image: {
asset: {
url: "...",
_id: "..."
}
}
}
}But you're trying to access props.url directly, which doesn't exist at that level.
Here's the fix:
Update your mapping in <ProjectCard /> to properly access the nested image:
{collaborators.map((collaborator) => (
<Avatar
key={collaborator.personReference._id}
url={collaborator.personReference.image}
/>
))}Then in your <Avatar /> component, pass the entire image object to urlFor:
const Avatar = (props) => {
return (
<StyledAvatar
css={{
backgroundImage: `url(${urlFor(props.url).url()})`,
}}
/>
);
};The urlFor() function from @sanity/image-url is smart enough to handle the image object structure (with the asset reference) and build the proper CDN URL.
Alternative approach - you could also simplify your GROQ query to flatten the structure:
"collaborators": *[_type == "article" && references(^._id)]| order(publishedAt desc){
"personImage": personReference->image,
"personId": personReference->_id
}[0...3]Then access it like:
{collaborators.map((collaborator) => (
<Avatar
key={collaborator.personId}
url={collaborator.personImage}
/>
))}Either approach should work! The key is making sure you're passing the complete image object (with the asset reference) to urlFor(), which will handle building the optimized CDN URL for you.
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.