Next.js Discord

Discord Forum

Splitting Homepage for Real-Time Updates

Unanswered
Havana posted this in #help-forum
Open in Discord
HavanaOP
Hello! I've been working on a homepage that shows products from a database. At first, my code looked like this:

// Home Page Component Before Splitting.
export default async function Home() {
    const supabase = createServerComponentClient({ cookies });
    const { data: Products } = await supabase.from("Products").select("*").order("id", { ascending: false });

    return (
        <div className="grid gap-4">
            {products?.map((product) => (
                <ProductCard key={product.id} {...product} />
            ))}
        </div>
    );
}


But I wanted to make it so the page updates in real-time when the database changes. To do that, I needed to use useEffect. (Which requires a client component) So, I split the homepage into two parts: the original homepage and a new component called ProductsPage.

// Home Page Component After Splitting.
export default async function Home() {
    const supabase = createServerComponentClient({ cookies });
    const { data: Products } = await supabase.from("Products").select("*").order("id", { ascending: false });

    return (
        <div className="grid gap-4">
            <ProductsPage products={Products || []} />
        </div>
    );
}


Here's the ProductsPage component:

// ProductsPage Component
export default function ProductsPage({ products }: { products: Product[] }) {
    useEffect(() => {
        // ...
    }, []);

    return products?.map((product) => <ProductCard key={product.id} {...product} />);
}


After that I start getting this error:

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.


Note: The ProductCard component is a Server component.

4 Replies

HavanaOP
Some other errors I'm getting:
Error: Unknown root exit status.

Error: There was an error while hydrating. Because the error happened outside of a Suspense boundary, the entire root will switch to client rendering.

Error: supabaseKey is required. (From ProductCard component)
Scottish Fold
you cannot use async function in 'use client' pages. To achieve real time updates with Supabase you can work with Supabase Realtime in the client page / client component. Here an example code that allows you to init the products with the server data then update on real time
'use client'

import { useEffect, useState } from 'react'
import supabase from '@/utils/supabase'

export default function RealtimePosts({ serverPosts = [] }: { serverPosts: any }) {
  const [products, setProducts] = useState(serverPosts)

  useEffect(() => {
    setPosts(serverPosts)
  }, [serverPosts])

  useEffect(() => {
    const channel = supabase
      .channel('*')
      .on('postgres_changes', { event: 'INSERT', schema: 'public', table: 'posts' }, (payload) =>
        setProducts((products: any) => [...products, payload.new])
      )
      .subscribe()

    return () => {
      supabase.removeChannel(channel)
    }
  }, [serverProducts])

  return <ProductsPage products={products} />
}
the error "supabaseKey" is required is because in client you must use NEXT_PUBLIC_SUPABASE_KEY and NEXT_PUBLIC_ANON_KEY
remember of enabling realtime in the supabase for your table products and also configure the RLS to allow anon or authenticated users to read it / receive realtime updates https://supabase.com/docs/guides/realtime