Search code examples
reactjsnext.jssanity

Posts in my .map() function are not displaying on browser


I have run through my code countless times but I can't make out the problem. I am following a blog build tutotial with Nextjs 13.4 with Sanity.io.

In my BlogList component, a console log of my posts reveals all my post in the terminal alright, but when I map the post into the UI, nothing shows up on my page.

There is no indication of an error anywhere. I would love it if you could take a second look at the code. You might find something I missed.

page.tsx - Blog Home Page

import { draftMode } from "next/headers";
import { groq } from "next-sanity";
import { client } from "@/lib/sanity.client";
import BlogList from "@/components/blog/BlogList.tsx";
import BlogHeader from "@/components/blog/BlogHeader";
import PreviewSuspense from "@/components/studio/PreviewSuspense";
import PreviewBlogList from "@/components/studio/PreviewBlogList";

const query = groq`
  *[_type=='post'] {
    ...,
    _id,
    _createdAt,
    author->,
    "slug": slug.current
  } | order(_createdAt desc)
`;

export default async function page() {
  const { isEnabled } = draftMode();
  if (isEnabled) {
    return (
      <PreviewSuspense
        fallback={
          <div role="status">
            <p className="text-center text-lg animate-pulse text-blue-800">
              Loading Draft Data
            </p>
          </div>
        }
      >
        <PreviewBlogList query={query} />
      </PreviewSuspense>
    );
  }

  const posts = await client.fetch<Post[]>(query);
  // console.log(posts);
  return (
    <>
      <BlogHeader />
      <section
        id="blog"
        className="w-full xl:pt-10 xl:pb-24 pb-12 p-4 flex flex-col gap-10 xl:gap-0 align-middle items-center border-b-[1px] border-b-gray-300 dark:border-b-gray-500"
      >
        <BlogList posts={posts} />
      </section>
    </>
  );
}

BlogList.tsx - Blog List Component - Nothing on this page especially content in the .map() function shows up on the page. Any Content outside of the .map() function shows up though.

import Image from "next/image";
import { urlForImage } from "../../../sanity/lib/image";

interface Props {
  posts: Post[];
}

export default function BlogList({ posts }: Props) {
  console.log(posts);
  return (
    <>
      <div className="grid grid-cols-1 gap-8 mt-8 md:mt-16 md:grid-cols-2 xl:grid-cols-3">
        {posts.map((post) => {
          <div key={post._id} className="group cursor-pointer">
            <div className="relative w-full h-64 lg:h-80 group-hover:scale-105 drop-shadow-xl">
              <Image
                className="object-cover object-center rounded-lg"
                src={urlForImage(post.mainImage).url()}
                alt={post.author.name}
                fill
              />

              <h1>hello there</h1>

              <div className="absolute bottom-0 flex p-3 bg-white dark:bg-gray-900 ">
                <Image
                  className="rounded-full"
                  src={urlForImage(post.author.image).url()}
                  alt={post.author.name}
                  width={10}
                  height={10}
                />

                <div className="mx-4">
                  <h1 className="text-sm text-gray-700 dark:text-gray-200">
                    {post.author.name}
                  </h1>
                  <p className="text-sm text-gray-500 dark:text-gray-400">
                    {new Date(post._createdAt).toLocaleDateString("en-US", {
                      day: "numeric",
                      month: "numeric",
                      year: "numeric",
                    })}
                  </p>
                </div>
              </div>
            </div>

            <h1 className="mt-6 text-xl font-semibold text-gray-800 dark:text-white">
              {post.title}
            </h1>

            <hr className="w-32 my-6 text-blue-500" />

            <p className="text-sm text-gray-500 dark:text-gray-400">
              Lorem ipsum dolor sit amet consectetur adipisicing elit.
              Blanditiis fugit dolorum amet dolores praesentium, alias nam?
              Tempore
            </p>

            <a
              href="#"
              className="inline-block mt-4 text-blue-500 underline hover:text-blue-400"
            >
              Read more
            </a>
          </div>;
        })}
      </div>
    </>
  );
}

Console Log for my Posts

[
  {
    slug: 'blog-development-with-next-13-4-and-sanity',
    mainImage: { _type: 'image', alt: 'Cover Image', asset: [Object] },
    publishedAt: '2023-06-14T11:15:00.000Z',
    _type: 'post',
    categories: [ [Object], [Object] ],
    title: 'Blog Development with Next 13.4 and Sanity',
    author: {
      name: 'Edward Opoku-Agyemang',
      _updatedAt: '2023-06-14T11:11:24Z',
      slug: [Object],
      image: [Object],
      _createdAt: '2023-06-14T11:11:24Z',
      _rev: 'sKRwurG6U83UyjXGn2pQeT',
      _type: 'author',
      bio: [Array],
      _id: '46ec3787-817d-441f-be7b-eab31e9ed3db'
    },
    _id: '0fa6470e-f88f-46d7-a127-a932b0f148fb',
    _updatedAt: '2023-06-14T11:15:49Z',
    _createdAt: '2023-06-14T11:15:33Z',
    _rev: 'TrPpVOhlpnRSDfzu76fyos',
    body: [ [Object], [Object], [Object], [Object] ]
  }
]

Solution

  • You are not returning anything from the map in BlogList.tsx

    {posts.map((post) => {

    You just need to remove the { and the } from the end of the map. This will do an implicit return and return the markup.

    Alternative you need to do

    {posts.map((post) => {
    return (<div></div>)
    }