Search code examples
javascriptreactjsnext.jsserver-side-renderingnext.js13

Does 'use client' in Next.js 13 root layout make whole routes client component?


I was trying Nextjs 13 with Next-auth and Apollo Client. For that we wrap the root layout with the providers but we also need 'use client' to be specified. I have no problem with the libraries.

But what is confusing to me is that nextjs 13 app dir uses a server-first approach by default, and if I treat the root layout as a client, does it make all the pages client? Because, afak, the root layout is the parent of whole routes

Github discussion


Solution

  • from here (thanks to Paul Serre for commenting)

    The root layout is a Server Component by default and can not be set to a Client Component.

    in app directory, server components can render client components but client components cannot render server components. Because

    Since Client Components are rendered after Server Components, you cannot import a Server Component into a Client Component module (since it would require a new request back to the server). Instead, you can pass a Server Component as props to a Client Component.

    the only exception is if the client component renders component which is passed as children. this is a Layout. From the same docs:

    Layouts are Server Components by default but can be set to a Client Component.

    "use client";
    
    export default function Layout({children}: {
      children: React.ReactNode
    }) {
      return (
        <html lang="en">        
          <head />
          <body>{children}</body>
        </html>
      )
    }
    

    Since the root layout component is rendering children, any component inside children tree can be server component

    this would not be accepted

    "use client";
    
    export default function Layout({children}: {
      children: React.ReactNode
    }) {
      return (
        <html lang="en">        
          <head />
          <body> 
             // if you manually pass server component inside client component
             <AnyServerRenderedComponent/>
          </body>
        </html>
      )
    }