Currently, I am upgrading my next.js 14 project to next.js 15 with React 19, And I am Facing this issue I will be glad if you can help me.
this is my app home page which is e-com website
export const revalidate = 0;
import Container from "./components/Container";
import HomeBanner from "./components/HomeBanner";
import NullData from "./components/NullData";
import getProducts, { IProductParams } from "@/actions/getProducts";
import ShuffledProducts from "./components/ShuffledProducts"; // Direct import
interface HomeProps {
searchParams: IProductParams;
}
export default async function Home({ searchParams }: HomeProps) {
const { category, searchTerm } = searchParams;
// Fetch products from the server
const products = await getProducts({ category, searchTerm });
if (products.length === 0) {
return <NullData title="OOPS ! No Products Found" />;
}
return (
<div className="p-8">
<Container>
<div className="pb-8">
<HomeBanner />
</div>
{/* Directly render the Client Component */}
<ShuffledProducts products={products} />
</Container>
</div>
);
}
and this is my container (which is imported to the above page)
interface ContainerProps{
children: React.ReactNode
}
const Container: React.FC<ContainerProps> = ({ children }) => {
return (<div className="
max-w-[1920px]
mx-auto
xl:px-20 md:px-2 px-4">{children}</div>);
};
export default Container;
and this is my ShuffledProducts
"use client";
import ProductCard from "./products/ProductCard";
interface ShuffledProductsProps {
products: any[];
}
export default function ShuffledProducts({ products }: ShuffledProductsProps) {
function shuffleArray(array: any[]) {
for (let i = array.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[array[i], array[j]] = [array[j], array[i]];
}
return array;
}
const shuffledProducts = shuffleArray(products);
return (
<div
className="grid
grid-cols-2
sm:grid-cols-3
lg:grid-cols-6
xl:grid-col-5
2xl:grid-col-6
gap-8"
>
{shuffledProducts.map((product: any) => (
<ProductCard key={product.id} data={product} />
))}
</div>
);
}
and this is my getproducts
import prisma from "@/libs/prismadb";
export interface IProductParams {
category?: string | null;
searchTerm?: string | null;
}
export default async function getproducts(params: IProductParams) {
try {
const { category, searchTerm } = params;
let searchString = searchTerm;
if (!searchTerm) {
searchString = "";
}
const query: any = {};
if (category) {
query.category = category;
}
const products = await prisma.product.findMany({
where: {
...query,
OR: [
{
name: {
contains: searchString,
mode: "insensitive",
},
description: {
contains: searchString,
mode: "insensitive",
},
},
],
},
include: {
reviews: {
include: {
user: true,
},
orderBy: {
createdDate: "desc",
},
},
},
});
return products;
} catch (error: any) {
console.error("Error fetching products:", error);
throw new Error("Failed to fetch products.");
}
}
my problem is I am getting blow console errors
Console Error
async/await is not yet supported in Client Components, only Server Components. This error is often caused by accidentally adding `'use client'` to a module that was originally written for the server.
Console Error
A component was suspended by an uncached promise. Creating promises inside a Client Component or hook is not yet supported, except via a Suspense-compatible library or framework.
and also I getting this error in terminal
Error: Route "/" used `searchParams.category`. `searchParams` should be awaited before using its properties. Learn more: https://nextjs.org/docs/messages/sync-dynamic-apis
at category (srcapppage.tsx:14:10)
12 |
13 | export default async function Home({ searchParams }: HomeProps) {
> 14 | const { category, searchTerm } = searchParams;
| ^
15 |
16 | // Fetch products from the server
17 | const products = await getProducts({ category, searchTerm });
In my Next.js 14 version those errors were not happed, I hope your help to resolve those errors in my Next.js 15 project.
Next.js 15 introduced some breaking changes including asynchronous params
Here is the example from the docs how your pages params must look to be compatible with new Next.js version:
// Before (Next.js 14)
type Params = { slug: string }
export default async function Page({params,}: {params: Params}) {
const { slug } = params
}
// After (Next.js 15+)
type Params = Promise<{ slug: string }>
export default async function Page(props: {params: Params}) {
const params = await props.params
const slug = params.slug
}
So, code of your home page should look similar to this:
export const revalidate = 0;
import Container from "./components/Container";
import HomeBanner from "./components/HomeBanner";
import NullData from "./components/NullData";
import getProducts, { IProductParams } from "@/actions/getProducts";
import ShuffledProducts from "./components/ShuffledProducts"; // Direct import
interface HomeProps {
searchParams: Promise<IProductParams>; // wrapped into Promise<>
}
export default async function Home({ searchParams }: HomeProps) {
const { category, searchTerm } = await searchParams; // await added
// Fetch products from the server
const products = await getProducts({ category, searchTerm });
if (products.length === 0) {
return <NullData title="OOPS ! No Products Found" />;
}
return (
<div className="p-8">
<Container>
<div className="pb-8">
<HomeBanner />
</div>
{/* Directly render the Client Component */}
<ShuffledProducts products={products} />
</Container>
</div>
);
}
Also instead of doing such refactoring manually, you can call special cli command from the docs to do this stuff automatically:
npx @next/codemod@canary upgrade latest
Another problem that Next.js is complaining about
async/await is not yet supported in Client Components
may be because you export server function getproducts without using 'use server'
directive
Just add 'use server'
to the top of your file:
'use server'; // << ADD THIS
import prisma from "@/libs/prismadb";
export interface IProductParams {
category?: string | null;
searchTerm?: string | null;
}
export default async function getproducts(params: IProductParams) {
try {
const { category, searchTerm } = params;
let searchString = searchTerm;
... other code