Issue with rendering a blockContent element nested inside an array in Gatsby

3 replies
Last updated: Apr 8, 2020
Hello, I'm trying to render a blockContent element I have inside of an array (used as an object inside a document)
But I can't figure out how to get the _raw data for the blocks properly, when a blockContent element is nested inside of an array it seems to not make it's own _raw element for Gatsby, instead it's a part of the _raw element from for the page.

Code in comments
AI Update

When working with blockContent (Portable Text) nested inside an array in Sanity with Gatsby, you're running into a common pattern where the _raw fields work differently than you might expect. Here's how to handle this:

Understanding _raw Fields with Nested Arrays

The gatsby-source-sanity plugin generates _raw fields only for top-level document fields, not for fields nested within arrays or objects. As you've discovered, when you have blockContent inside an array, you won't get individual _rawFieldName fields for those nested items.

Solution: Access via Parent _raw Field

Instead of looking for _rawBlockContent on individual array items, you need to:

  1. Query the parent array's _raw field - For instance, if your array field is called sections, query _rawSections
  2. Use resolveReferences to expand any references within that raw data

Here's an example query structure:

query MyPageQuery {
  sanityPage {
    sections {
      # Regular fields work fine here
      _key
      _type
    }
    # Access the raw blockContent through the parent array's _raw field
    _rawSections(resolveReferences: {maxDepth: 5})
  }
}

Working with the Data

In your component, you'd then access the blockContent like this:

const Page = ({ data }) => {
  const { sections, _rawSections } = data.sanityPage
  
  return (
    <>
      {_rawSections?.map((section, index) => {
        // Now you have access to the full raw blockContent
        if (section._type === 'textSection' && section.content) {
          return (
            <PortableText
              key={section._key}
              value={section.content} // This is your blockContent
            />
          )
        }
        return null
      })}
    </>
  )
}

Key Points

  • "For instance, a field named body will be mapped to _rawBody" - but this only applies to document-level fields, not nested ones
  • The resolveReferences parameter with maxDepth helps expand any referenced documents within your blockContent
  • You access nested blockContent through the parent field's _raw version (like _rawSections for a sections array)
  • The entire array structure is preserved in the _raw field, including all nested blockContent

This is the intended behavior of the plugin - raw fields are generated at the document root level to avoid excessive complexity in the GraphQL schema. By querying the parent array's _raw field, you get the complete nested structure including your blockContent elements.

My GraphQL query looks like this:const data = useStaticQuery(graphql`
    
{
      
sanityUserTesting {
        
userTestingIntro {
          
auditButton
          
mostSold
          
testTitle
          
testFeatures {
            
features
          
}
        
}
        
_rawUserTestingIntro
      
}
    
}
  ``)`


_rawUserTestingIntro
contains the elements I need, inside the
_rawUserTestingIntro
array there is an array called
_rawUserTestingIntro
I'm trying to loop over this while I loop over some other values from the query

My loop currently looks like this

return (
    
<>
      
{data.sanityUserTesting.userTestingIntro.map((node, index) => {

        
return (
          
<>

        
            
<BlockContent

              _blocks_={
                
data.sanityUserTesting._rawUserTestingIntro.auditDescirption[
                  
index
                
]
              
}

              _serializers_={defaultSerializer}
            
/>

            
{node.auditButton}
          
</>
        
)
      
})}
    `&lt;`/&gt;
  )
}
If I console.log
data.sanityUserTesting._rawUserTestingIntro
I get the following . So I've tried
settings_data.sanityUserTesting._rawUserTestingIntro.auditDescirption[index]_
as the block element source, but this gives me a 0 error. If Any ideas? 🙂
I have been struggling with this issue for so long today, but writing this questions made me solve it! I had the [index] on the wrong spot, the right way refer to the block elements was
<BlockContent

              _blocks_={
                
data.sanityUserTesting._rawUserTestingIntro[index]
                  
.auditDescirption
              
}

              _serializers_={defaultSerializer}
            
/>

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.

Was this answer helpful?