14

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

Yilmaz
  • 35,338
  • 10
  • 157
  • 202
A.Anvarbekov
  • 955
  • 1
  • 7
  • 21
  • 3
    regarding to document you can have client component as parent and server components as children, check this out : https://beta.nextjs.org/docs/rendering/fundamentals#component-level-client-and-server-rendering – Hesam Jan 14 '23 at 20:11

2 Answers2

16

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. 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>
  )
}
Yilmaz
  • 35,338
  • 10
  • 157
  • 202
  • 1
    Can you be a little more clear with your example? I can't see any client component here. Weren't you saying that the client component should render the children passed to it as server components? I don't see a `use client` directive anywhere – sayandcode Feb 19 '23 at 04:23
  • @sayandcode i did not say this `the client component should render the children passed to it as server components` – Yilmaz Feb 19 '23 at 04:27
  • @sayandcode I said, if you pass `children` prop to a client component, any component inside `children tree` can be a server component – Yilmaz Feb 19 '23 at 04:29
  • Oh, so as per your edited answer, `{children}` should work as a server component, but explicit `` wont work as a server component, within a layout that has a `use client` directive? – sayandcode Feb 19 '23 at 08:06
  • 2
    @sayandcode correct. It is true for all client components, not just for layout – Yilmaz Feb 19 '23 at 13:35
  • Reference for this matter: https://nextjs.org/docs/getting-started/react-essentials#recommended-pattern-passing-server-components-to-client-components-as-props – R-deBruijn May 23 '23 at 13:43
  • The doc literally says : `The root layout is a Server Component by default and can not be set to a Client Component.` https://nextjs.org/docs/app/building-your-application/routing/pages-and-layouts so I'm really confused about this answer being the accepted one – Paul Serre Jun 22 '23 at 15:26
  • @PaulSerre you are right. I was just learning nextjs13 at that time did not pay attention that much. I updated the answer referencing your comment. It makes sense though, if `RootLayout` was client your app would be a client side app :) – Yilmaz Jun 22 '23 at 15:40
  • @Yilmaz No worries, I'm currently struggling migrate to app folder so I don't know much yet either. In this link https://nextjs.org/docs/getting-started/react-essentials, they tell that if you want to put it at `RootLayout, you have to create a Client component with use-client directive, and put it into the RootLayout. – Paul Serre Jun 22 '23 at 15:43
  • @PaulSerre you can use `use client` anywhere except `RootLayout`. if you could make `RootLayout` client then app directory would be pointless – Yilmaz Jun 22 '23 at 15:47
  • Yes I know, it's not what I'm telling to do. I say that you have to create a Providers component with use-client directive and children props, put all your contexts here, and then use it in RootLayout – Paul Serre Jun 22 '23 at 15:50
  • @PaulSerre I already mentioned this "server components can render client components". `RootLayoout` server and can render cleint components – Yilmaz Jun 22 '23 at 15:58
5

[EDIT]

Even with the solution below, I couldn't make it work because of CSS-in-JS libraries, MUI and emotion in my case. You can check if yours is supported on this link:

https://nextjs.org/docs/app/building-your-application/styling/css-in-js

For me, Vercel rushed with its use of server components. They released NextJS 13 claiming it was stable, but if it's incompatible with a large portion of UI frameworks, it's completely useless. Especially if it's a front-end framework... This habit that engineers have of always wanting to use the latest technologies is exhausting.


As the doc said, here: https://nextjs.org/docs/getting-started/react-essentials you can't put 'use client' directive on the RootLayout, but you can create a Client component with children props and use it in your RootLayout

'use client'
 
import { ThemeProvider } from 'acme-theme'
import { AuthProvider } from 'acme-auth'
 
export function Providers({ children }) {
  return (
    <ThemeProvider>
      <AuthProvider>{children}</AuthProvider>
    </ThemeProvider>
  )
}

And then:

import { Providers } from './providers'

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <Providers>{children}</Providers>
      </body>
    </html>
  )
}
Paul Serre
  • 457
  • 3
  • 11