How to create context in a React Server Component in Next.js

React Server Components have been really on my mind lately. Every week I discover a new Gotcha you should know about. If you want to learn more about React Server Components then check out this post first.

Let's focus on passing context with React Server Components in this blog post.

You cannot create React Context inside a Server Component

You cannot create React Context inside a server Component. Remember, every component by default is a Server component in the Next 13 app directory 😳.

Well, you might think, let's convert the top-level component to a Client Component.

Umm, you can't either, remember? You cannot make a Server Component a child of the Client, and if you make the Root component a Client, then every single component in the project will be a child, so we will have to say goodbye 👋 to Server Components.

What's the workaround 👇

Let's say you want to add dark mode to your app. We can create a ThemeProvider for it and store the value as dark or light. The best place to do this would be RootLayout, i.e. the root of the tree.

What is Root Layout in Next.js?

A root layout is the top most layout like the name indicates 'root'. It allows you to modify the initial HTML returned from the server.

The app directory will contain a Root Layout i.e. a layout.tsx file by default.

The RootLayout might look like this.

import './globals.css';
import type { Metadata } from 'next';
import { Inter } from 'next/font/google';

const inter = Inter({ subsets: ['latin'] });

export const metadata: Metadata = {
  title: 'Create Next App',
  description: 'Generated by create next app',
};

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

Creating Context only works in Client Components

Since context providers are typically rendered near the root of an application to share global concerns, like the current theme. Because context is not supported in Server Components, trying to create a context at the root of your application will cause an error like the one below ❌

You're importing a component that needs createContext. It only works in a Client Component but none of its parents are marked with "use client", so they're Server Components by default.

Learn more: https://nextjs.org/docs/getting-started/react-essentials

Hence we can create a ThemeProvider, mark it as use client and pass that on.

Here's how to pass React Context 👇

Snippet for how to pass context in Next.js with Server Components

You can click on this image to copy the snippet ✨

With the provider rendered at the root, all other Client Components throughout your app can consume this context.

Resources:

That's a wrap, hope this post was useful. 🙌 Please let me know on Twitter how you like it and show some love.

Last updated:

. . .

Learn React Server Components

A FREE 1-week course to teach you all about React Server Components step-by-step!

  • 🤔 What Server and Client Components are, their differences?
  • 🚀 The difference between Server-side Rendering & Server Components
  • 👏 Advanced: Best Practices and more

Enter your email, and you'll be notified when the course starts

No spam, unsubscribe anytime.