Providers inside RootLayout in Next.js

3 min read

When building a Next.js application by default each page and component is rendered on the server side it is called Server Component. We can change it and render a component on the client side by using 'use client' directive on the top of the file as in the example below

'use client'

export const MyButton = () => {
	return (
		<button >
			Click me!
		</button>
	);
};

Using Global Providers

What if we want to use a Provider to, for example, some Context for a Theme? We may be concerned whether it is ok to wrap our entire application with a Provider that uses the 'use client' directive. Rushing with the answer, let's create a Theme Provider.

'use client';

import { ThemeProvider } from 'next-themes';
import { ReactNode } from 'react';

export function Providers({ children }: { children: ReactNode }) {
  return <ThemeProvider attribute="class">{children}</ThemeProvider>;
}

To use the Theme we need to wrap our application with this Provider, and the documentation says that Providers should be used in the RootLayout. Let's do it

import { Providers } from "./providers";

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

We just wrapped out the entire application with Providers that use the 'use client' directive, does it mean that each page and component is rendered on the client side? The answer is NO.

When Component becomes Client Component

As I mentioned component and page become Client Components when we use the 'use client' directive or if we import it inside another Client Component, but if the page or component is passed via e.g. children prop it is still rendered on the Server Side, that's why it is ok to use Providers inside Root Layout