Issue with displaying the author's photo in a blog article

11 replies
Last updated: Apr 24, 2023
Hey everyone, can anyone help me solve this issue?
*DESIRED RESULT*: I want the author’s photo to be displayed with each blog article. (Example image attached)

*ISSUE*: The author’s image is not displaying.


Here is my blog page schema:
const blogMain = {
    name: 'post',
    title: 'Post',
    type: 'document',
    fields: [
      {
        name: 'title',
        title: 'Title',
        type: 'string',
      },
      {
        name: 'slug',
        title: 'Slug',
        type: 'slug',
        options: {
          source: 'title',
          maxLength: 96,
        },
      },
      {
        name: 'content',
        title: 'Content',
        type: 'array',
        of: [{ type: 'block' }],
      },
      {
        name: 'excerpt',
        title: 'Excerpt',
        type: 'string',
      },
      {
        name: 'coverImage',
        title: 'Cover Image',
        type: 'image',
        options: {
          hotspot: true,
        },
        fields: [
            {
                name: "alt",
                title: "Alt",
                type: "string",
            },
        ],
      },
      {
        name: 'date',
        title: 'Date',
        type: 'datetime',
      },
      {
        name: 'author',
        title: 'Author',
        type: 'reference',
        to: { type: 'author' },
      },
    ],
    preview: {
      select: {
        title: 'title',
        author: 'author.name',
        media: 'coverImage',
      },
      prepare(selection: { author: any }) {
        const { author } = selection
        return { ...selection, subtitle: author && `by ${author}` }
      },
    },
  }

  export default blogMain

And here is my GROQ:
export async function getPosts(): Promise<Post[]> {
    return createClient(clientConfig).fetch(
        groq`*[_type == "post"]{
            _id,
            _createdAt,
            title,
            "slug": slug.current,
            alt,
            excerpt,
            "coverImage": coverImage.asset->url,
            date,
            "author": author->{name, picture},
        }`
    );
}

Here’s my component in Next:
const BlogPosts = async () => {
    const posts = await getPosts();
    const displayPosts = posts.map((post) => {
        return (
            <div className="max-w-sm rounded overflow-hidden shadow-lg">
                <Link
                    href={`/posts/${post.slug}`}
                    key={post._id}
                >
                    {post.coverImage && (
                        <Image
                            src={post.coverImage}
                            alt={post.title}
                            width={750}
                            height={300}
                            className="object-cover rounded-lg border border-gray-500"
                        />
                    )}
                    <div className="px-6 py-4">
                        <div className="font-bold text-xl mb-2">
                            {post.title}
                        </div>
                        <Image
                            src={post.author.picture}
                            alt="something"
                            width={50}
                            height={50}
                            className="object-cover rounded-lg border border-gray-500"
                        />
                        <div className="font-bold text-sm mb-2">
                            {post.author.name}
                            {post.date}
                        </div>
                        <p className="text-gray-700 text-base">
                            {post.excerpt}
                        </p>
                    </div>
                </Link>
            </div>
        );
    });

    return <div>{displayPosts}</div>;
}

export default BlogPosts;

Apr 23, 2023, 8:31 PM
inspecting the html in chrome what does the src= value have? when console logging the post what is the value for coverImage?
Apr 23, 2023, 8:38 PM
Hi Parker,chrome devtools shows:

<img alt="something" width="50" height="50" decoding="async" data-nimg="1" class="object-cover rounded-lg border border-gray-500" src="" style="">
Looks like it’s going straight the alt..

Console.log:

<https://cdn.sanity.io/images/ta7lvil7/production/10f3521c92769c03c200b311aeecc3814e0b7f66-1280x720.jpg>
Warning: Each child in a list should have a unique "key" prop.

Check the top-level render call using <div>. See <https://reactjs.org/link/warning-keys> for more information.
    at div
Apr 23, 2023, 8:44 PM
sorry I pasted the wrong source, please check again if you have previously
Apr 23, 2023, 8:46 PM
I’m learning typescript on this project as well, is this a typescript issue?
Apr 23, 2023, 8:51 PM
Here’s my Types file:
Apr 23, 2023, 8:53 PM
When I log the author image, I’m getting the object back:
AUTHOR IMAGE:  {
  crop: { top: 0, left: 0, bottom: 0, _type: 'sanity.imageCrop', right: 0 },
  hotspot: { x: 0.5, y: 0.5, height: 1, _type: 'sanity.imageHotspot', width: 1 },
  _type: 'image',
  asset: {
    _ref: 'image-efbbe065b6589bd853935500e85084e4566cf5e4-512x512-png',
    _type: 'reference'
  }
}
Apr 23, 2023, 10:16 PM
You’ll need to expand the author’s image’s asset or pass the asset to a configured imageUrl builder function. Expanding the asset would look like this:
author->{
  name, 
  picture{
   ...,
   'url': asset->url
  }
}
Apr 24, 2023, 4:39 PM
Thanks RD. That’s good to know and thanks for your help. I wound up using the imageUrl builder but needed to use the createClient from @sanity/client as well. Is this the standard practice?
const builder = imageUrlBuilder(createClient({
        projectId: "abcd1234",
        dataset: "production",
      }));
Apr 24, 2023, 4:43 PM
Yep, that will work! You can also just reuse the client you’ve already configured for your project if you have one.
Apr 24, 2023, 4:45 PM
Thank you very much.
Apr 24, 2023, 4:46 PM
You’re welcome!
Apr 24, 2023, 4:46 PM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?