AboutArticlesGame

Do Contexts in Next.js 13 Make the Whole App Render on the Client?

Cover Image for Do Contexts in Next.js 13 Make the Whole App Render on the Client?
Dennis Persson
Dennis Persson

URL copied to clipboard

4 minutes reading

React contexts are quite crucial for React development. Most projects depends on it, either directly or through libraries. The question is, can they be used with Next.js 13 App Router? And can the application still benefit from the power of Server Components when contexts are used? Let's answer that!

In This Article

Difference Between Client and Server Components

For this article to make sense, you should have grasp about what the difference between Client Components and Server Components are. In Short, Client Components are regular old React components rendered with JavaScript on the client, while Server Components are React components which are rendered into HTML on the server. The rendered Server Components can then be used as none-interactive components anywhere in the applications React tree.

Does it make sense? If not, you can learn more about Server Components, read Next.js docs about it or my article about, why Server Components matter.

Can I Use React Context in Server Components?

React contexts are well used in React applications to share states between components. Since Client Components and Server Components are rendered on different machines, the client and the server, you might think that React contexts cannot be used.

Server Components are simply HTML markup which certainly don't have a React state. If you try to use a context in a Server Component it will throw an error.

ReactServerComponentsError:

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

-[/path/to/file/MyComponent.ts:1:1]
1 | import { useContext } from 'react'

While Server Components are incompatible with React contexts, Client Components can handle them perfectly fine. As long as you provide the context provider in a Client Component, all Client Components in that component's child-tree will be able to read and use the context. It doesn't matter whether you have any Server Components in the sub-tree or not, Server Components are HTML markup, which don't care!

Server components don't care meme It's not you, he's always like that...

Will My Complete Next.js Application Be Rendered on Client if I Use React Contexts?

The answer is no. Your whole site will not be forced to render on the client if you use React contexts. As mentioned, Server Components do not care about contexts, which also means it doesn't interfere with them.

Let's list a few statements about Next.js App Router.

  1. The RootLayout in Next.js is always a Server Component
  2. The children prop passed to RootLayout is also a Server Component
  3. Server Components can include Client Components (the Client Components will be ignored when the server renders the Server Component)
  4. Server Components can be included in Client Components if they are passed as children to the Client Component

Now look at this code example, it's taken from Next.js guide for how to set up contexts.

import { ContextProviders } from './providers';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <ContextProviders>{children}</ContextProviders>
      </body>
    </html>
  );
}

What we can see in that code is:

  • The Root Layout, which is a Server Component by statement #1
  • The ContextProviders component which includes the contexts is a Client Component (statement #3 allows that)
  • The children prop for the RootLayout is a Server Component (statement #2)
  • The children is passed to the ContextProviders Client Component (accepted by statement #4)

By default, Next.js can handle intervened Client and Server Components, and with this setup we are following all the rules of how to use the components. The above code will result in a React tree looking as below.

<RootLayout (Server Component)>
  <ContextProviders (Client Component)>
    <Page (Server Component)>
      <Potential other Client Components using the context />
      <Potential other Server Components ignoring the context />
    </Page>
  </ContextProviders>
</RootLayout>

Although using contexts work fine, it does create a bit of confusion. You must remember that you will only be able to use the context within Client Components, the context is not available on the server.

URL copied to clipboard

Dennis Persson

Knowledge Should Be Free

I'm doing this for free because I like to contribute to the world. Knowledge should be free and available to everyone. Still, we all need to make a living somehow, and running this blog takes time and effort. When I find content I value, I support those creators so they can keep doing their amazing work. If you enjoy what I'm sharing here, consider buying me a coffee. It doesn't have to cost more than a coffee!

Buy Me A Coffee

Related Articles

Cover Image for Write SOLID React Hooks

Write SOLID React Hooks

20 minutes readingArchitecture | Frontend | JavaScript | React

SOLID is one of the more commonly used design patterns. Each React article about SOLID presents the model in slightly different ways, some applies it on components, other on TypeScript, but very few of them are applying the principles to hooks

Cover Image for Answers to Common Next.js Questions

Answers to Common Next.js Questions

10 minutes readingFrontend | JavaScript | Next.js

Answers to common Next.js questions such as how Server Components work and how to read params in components

Cover Image for 33 Christmas Animations to Easily Add to Your Website

33 Christmas Animations to Easily Add to Your Website

3 minutes readingFrontend | UI

33 Christmas animation and interactive art which easily can be added you your website. Most of them are CSS only, others requires a small amount of JavaScript

Cover Image for React Hook: useElementDimensions

React Hook: useElementDimensions

9 minutes readingFrontend | Hooks | JavaScript | React

React hook useElementDimensions measures height, width and position of a node or element. It updates the dimensions on resize and scroll events

Browse articles