How to fetch the bio from author section to post in a blog?

4 replies
Last updated: Nov 8, 2021
Hey all! Curious if anyone was able to fetch ‘bio’ from the author section to post in blog. In my post.js I fetch title/publish date/ author image and name etc and can display via “`{postData.name}`” for example, but when I try to fetch bio with
"bio": author->bio
and then
{postData.bio}
I get “If you meant to render a collection of children, use an array instead.“:
useEffect(() => {

sanityClient

.fetch(
``*[slug.current == $slug]{`

title,

slug,

publishedAt,

mainImage{

asset->{

_id,

url

}

},

body,

"name": author->name,

"authorImage": author->image,

"bio": author->bio,

}
,`
{ slug }

)

.then((data) => setPostData(data[0]))

.catch(console.error);

}, [slug]);
AI Update

The issue you're encountering is because the bio field in your author schema is likely defined as a Portable Text (block content) field, not a simple string. When you fetch it with "bio": author->bio, you're getting an array of block objects, and React is throwing that error because it doesn't know how to render that array directly.

Here's how to fix it:

Install the Portable Text renderer:

npm install @portabletext/react

Then use it to render the bio:

import {PortableText} from '@portabletext/react'

// In your component
{postData.bio && <PortableText value={postData.bio} />}

This will properly render the rich text content with all its formatting.

Solution 2: Fetch Plain Text Only

If you just want the plain text without formatting, modify your GROQ query to use the pt::text() function:

sanityClient.fetch(
  `*[slug.current == $slug]{
    title,
    slug,
    publishedAt,
    mainImage{
      asset->{
        _id,
        url
      }
    },
    body,
    "name": author->name,
    "authorImage": author->image,
    "bio": pt::text(author->bio),
  }`,
  { slug }
)

Then you can display it normally:

{postData.bio}

Why This Happens

Portable Text fields store content as an array of block objects (like [{_type: 'block', children: [...]}]), not as simple strings. This structure allows for rich formatting, links, and custom blocks. React sees this array and doesn't know how to render it, hence the error message about using an array.

The @portabletext/react library knows how to traverse this structure and render it properly as HTML elements. If you only need plain text, the pt::text() function in your query extracts just the text content without the structure.

Hi Jennifer. It sounds like
bio
is a rich text field (you might also see it called block content or portable text), meaning that instead of rendering out a string, it’s trying to render an array. Sanity offers a tool to render portable text for you. If the
bio
field is portable text (the schema will be an array with
_type: 'block'
), then instead of using
{postData.bio}
on your front end, you’ll want to render it with the package linked above:

import BlockContent from '@sanity/block-content-to-react'

// ...

// In your function:
return (
  // ...
  <BlockContent blocks={postData.bio} />
)
If this is unclear or you can’t get it working, please let me know.
Worked like a charm thank you
user A
!
user K
This article was very helpful for me understanding Portable Text -&gt; Block Content https://www.sanity.io/guides/introduction-to-portable-text
Great! Thanks for following up, Jennifer.
James, sorry I missed your question. Because BlockContent is a default export from
block-content-to-react
, you can name it whatever you want when you import it (
import JamesContent from '@sanity/block-content-to-react
) and that’s what the component will be named when you go to use it (
<JamesContent blocks={body} />
).

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?