Reputation: 11
Beginner here building a website/e-commerce store using React, Next 14, Typescript, and Sanity for the CMS. I was following this tutorial here: https://www.youtube.com/watch?v=g2sE034SGjw&t
I'm receiving the following error:
unhandled runtime error
async/await is not yet supported in Client Components, only Server Components.
I have a parent component <ProductGridApp />
that is returning the child component <ProductGrid />
in a div, which is then rendered in Home() in page.tsx
I'm not using the "use client"
directive in either component, except for in page.tsx
, where the parent component <ProductGridApp />
is called.
Here is the code for <ProductGridApp />
:
import React from "react";
import { ProductGrid } from "./product-grid";
import { SanityProduct } from "../../imgsandbox/config/inventory";
import { siteConfig } from "../../imgsandbox/config/site";
import { client } from "../../imgsandbox/sanity/lib/client";
import { groq } from "next-sanity";
import "../components/local-css/card.css";
interface Props {
products: SanityProduct[];
}
export default async function ProductGridApp() {
const products = await client.fetch<SanityProduct[]>(
groq`*[_type == "product"]
{
_id,
_createdAt,
name,
sku,
images,
currency,
price,
description,
"slug": slug.current
}`
);
console.log(products);
return (
<div className="card card-text card-text-x">
<h1>{siteConfig.name}</h1>
<h3>{siteConfig.description}</h3>
<div>
<ProductGrid products={products} />
</div>
</div>
);
}
console.log("Shop Loaded");
Here is the code for <ProductGrid />
:
import Image from "next/image";
import Link from "next/link";
import { urlForImage } from "../../imgsandbox/sanity/lib/image";
import { XCircle } from "lucide-react";
import { formatCurrencyString } from "use-shopping-cart";
import { SanityProduct } from "../../imgsandbox/config/inventory";
interface Props {
products: SanityProduct[];
}
export function ProductGrid({ products }: Props) {
if (!products || products.length === 0) {
return (
<div className="mx-auto grid h-40 w-full place-items-center rounded-md border-2 border-dashed bg-gray-50 py-10 text-center dark:bg-gray-900">
<div>
<XCircle className="mx-auto h-10 w-10 text-gray-500 dark:text-gray-200" />
<h1 className="mt-2 text-xl font-bold tracking-tight text-gray-500 dark:text-gray-200 sm:text-2xl">
No products found
</h1>
</div>
</div>
);
}
return (
<div className="grid grid-cols-1 gap-x-6 gap-y-10 sm:grid-cols-3 lg:col-span-3 lg:gap-x-8">
{!products ||
products.map((product) => (
<Link
key={product._id}
href={`/products/${product.slug}`}
className="group text-sm"
>
<div className="aspect-h-1 aspect-w-1 w-full overflow-hidden rounded-lg border-2 border-gray-200 bg-gray-100 group-hover:opacity-75 dark:border-gray-800">
<Image
src={urlForImage(product.images[0])}
alt={product.name}
width={225}
height={280}
className="h-full w-full object-cover object-center"
/>
</div>
<h3 className="mt-4 font-medium">Name</h3>
<p className="mt-2 font-medium">Price</p>
</Link>
))}
</div>
);
}
What's worse, is that I'm not receiving errors in my Chrome Dev Tools console or in my VSCode terminal and am just receiving a blank white screen, so I'm really at a loss when trying to troubleshoot this. I've been looking at this problem for a few days now and can't do it on my own.
Can anyone help?
Upvotes: 1
Views: 176
Reputation: 2027
You can fetch the data on server side by using getServerSideProps
, thats what its for to construct the page and render page to user. But you can do this in the page component only.
This is how it will work
import React from "react";
import { ProductGrid } from "./product-grid";
import { SanityProduct } from "../../imgsandbox/config/inventory";
import { siteConfig } from "../../imgsandbox/config/site";
import { client } from "../../imgsandbox/sanity/lib/client";
import { groq } from "next-sanity";
import "../components/local-css/card.css";
interface Props {
products: SanityProduct[];
}
export default function ProductGridApp(props) {
console.info('props', props);
return (
<div className="card card-text card-text-x">
<h1>{siteConfig.name}</h1>
<h3>{siteConfig.description}</h3>
<div>
<ProductGrid products={props?.products || []} />
</div>
</div>
);
}
export const getServerSideProps = () => {
try {
const products = await client.fetch<SanityProduct[]>(
groq`*[_type == "product"]
{
_id,
_createdAt,
name,
sku,
images,
currency,
price,
description,
"slug": slug.current
}`
);
return {
props: {
products
}
}
} catch (error) {
return {
props: {
// use this to show error to user or perform other action based on this
error: 'an error occured'
}
}
}
}
Read more on getServerSideProps
here
Upvotes: 0