skip to Main Content

I’m working on a small app in Next.js, and I’ve not quite wrapped my head around the client-side vs server-side rendering.

I’ve been working from this great guide on setting up NextJS with Supabase.

According to the Next.js doc:

Once "use client" is defined in a file, all other modules imported into it, including child components, are considered part of the client bundle

So if I’m using an AuthProvider to wrap the app (as in the guide), but that AuthProvider is marked "use client", I’m wondering if the {children} in the layout are also automatically part of the client bundle.

My guess is "no", because they aren’t children of the AuthProvider, just adjacent ReactElements (or something), but I’d appreciate someone confirming and clarifying the terminology for me.

// AuthProvider.tsx

"use client";

...

// layout.tsx

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        <AuthProvider>
            {children}
        </AuthProvider>
      </body>
    </html>
  );
}

Thanks!

2

Answers


  1. You cannot call in a client component body a server component, but it’s totally fine to pass it as part of its props, for example with children as you can read on the doc:

    'use client'
     
    // This pattern will **not** work!
    // You cannot import a Server Component into a Client Component.
    import ExampleServerComponent from './example-server-component'
     
    export default function ExampleClientComponent({ children }) {
      const [count, setCount] = useState(0)
     
      return (
        <>
          <button onClick={() => setCount(count + 1)}>{count}</button>
     
          <ExampleServerComponent />
        </>
      )
    }
    

    But you can pass your server component to the client component as part of its props:

    'use client'
     
    import { useState } from 'react'
     
    export default function ExampleClientComponent({ children }) {
      const [count, setCount] = useState(0)
     
      return (
        <>
          <button onClick={() => setCount(count + 1)}>{count}</button>
     
          {children}
        </>
      )
    }
    
    // This pattern works:
    // You can pass a Server Component as a child or prop of a
    // Client Component.
    import ExampleClientComponent from './example-client-component'
    import ExampleServerComponent from './example-server-component'
     
    // Pages in Next.js are Server Components by default
    export default function Page() {
      return (
        <ExampleClientComponent>
          <ExampleServerComponent />
        </ExampleClientComponent>
      )
    }
    
    Login or Signup to reply.
  2. I am not pretty sure about the answer

    I had a similar situation couple of days ago & found a snippet of code that was of great benefit to me.

     import dynamic from "next/dynamic"
    const NoSSRWrapper = ({ children }: { children: JSX.Element }) => (
      <>{children}</>
    )
    
    export default dynamic(() => Promise.resolve(NoSSRWrapper), { ssr: false })
    

    Then you can wrap any part of your application (or your entire app) with this wrapper which prevents SSR and guarantee a CS components.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search