-
Notifications
You must be signed in to change notification settings - Fork 0
Description
Removed generateStaticParams
in /products/[id]/page.tsx
Due to Static-to-Dynamic Error
Overview
The /products/[id]
page encountered errors due to a conflict between static generation and dynamic cookie access. I removed generateStaticParams
to make the page dynamic (SSR), resolving the issue. This documents the problem, the fix, and a future solution to restore static generation.
Problem Description
The /products/[id]
page used generateStaticParams
to pre-render pages at build time, but fetchUser
(calling getUser
) accessed cookies, which isn’t possible during static generation. Additionally, Supabase’s createClient
tried to modify cookies during rendering, which is only allowed in Server Actions or Route Handlers.
Errors Encountered
-
Static-to-Dynamic Error:
Error: Page changed from static to dynamic at runtime /products/9b601a62-d80e-4f8c-83e3-82c3b41e2334, reason: cookies
- Caused by accessing cookies during runtime on a statically generated page.
-
Cookies Modification Error:
Error: Cookies can only be modified in a Server Action or Route Handler.
- Supabase’s
createClient
attempted to set cookies during Server Component rendering.
- Supabase’s
Affected Code
-
Original
generateStaticParams
(removed):export async function generateStaticParams() { const data = await getAllProducts().then((res) => res.data).catch(() => []); return data.length ? data.slice(0, 5).map((product) => ({ id: product.id })) : []; }
-
Problematic Code in
ProductDetailsPage
:const data = await fetchUser(); // Accesses cookies via getUser const productResponse = (data?.data?.id && (await fetchProductDetails(id, data.data.id))) || (await fetchProductDetails(id));
Resolution
I removed generateStaticParams
, making the page dynamic (SSR). This allows fetchUser
to access cookies at request time. I also added ISR to cache the page:
export const revalidate = 3600; // Revalidate every hour
Implications:
- Performance: SSR is slower than static generation, but ISR helps.
- SEO: Still SEO-friendly, but static pages are faster for crawlers.
- Scalability: Increased server load; monitor in production.
Suggested Future Solution
To restore static generation:
- Remove
fetchUser
fromProductDetailsPage
to avoid cookie access during rendering. - Fetch user data client-side in
ProductsClient
usingcreateBrowserClient
from@supabase/ssr
. - Reintroduce
generateStaticParams
to pre-render product pages.
Example:
-
Static
ProductDetailsPage
:export default async function ProductDetailsPage({ params }: { params: Promise<{ id: string }> }) { const { id } = await params; const productResponse = await fetchProductDetails(id); // No userId if (!productResponse.success || !productResponse.data) notFound(); const { product, category, isInCart, isInWishlist } = productResponse.data; return <ProductsClient product={product} category={category} isInCart={isInCart} isInWishlist={isInWishlist} userId={null} />; }
-
Client-Side User Fetch in
ProductsClient
:useEffect(() => { const fetchUserData = async () => { const supabase = createBrowserClient(process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!); const { data: { user } } = await supabase.auth.getUser(); if (user) setUserId(user.id); // Fetch isInCart, isInWishlist similarly }; fetchUserData(); }, []);
Next Steps
- Monitor performance in production to ensure SSR with ISR is sustainable.
- Consider implementing the static generation solution for better SEO and performance.
- Investigate cookies modification issue if it reappears (check Supabase auth setup).
Additional Notes
- Context: Rezogifts (e-commerce for gaming gift cards) using Next.js App Router and Supabase.
- Priority: Medium (current fix works, but static generation is preferred for SEO).