Server/Client Components in Next.js


Objectives

Learn the difference between server and client components in Next.js.

Rendering Environments

  • The client is the user's browser that requests your application code from the server and translates the server's response into a user interface.
  • The server is the data center computers that stores your application code, processes client requests, performs computations, and sends suitable responses.

Server Components

Server components offer developers enhanced capabilities to optimize the utilization of server infrastructure. By utilizing server components, developers can efficiently relocate data fetching operations to the server, in closer proximity to the database.

Use Cases

  • Fetch data
  • Access backend resources (directly)
  • Keep sensitive information on the server (access tokens, API keys, etc)
  • Keep large dependencies on the server / Reduce client-side JavaScript

Keeping Server-Only Code out of Client Components (Poisoning)

While making the variable public would make the function work on the client, it would leak sensitive information. So, this function was written with the intention that it would only ever be executed on the server.

Install "server-only" package, then any Client Component that imports getData() will receive a build-time error explaining that this module can only be used on the server.

Client Components

Client Components enable you to add client-side interactivity to your application. In Next.js, they are pre-rendered on the server and hydrated on the client. The "use client" directive is a convention to declare a boundary between a Server and Client Component module graph.

Use Cases

  • Add interactivity and event listeners (onClick(), onChange(), etc)
  • Use State and Lifecycle Effects (useState(), useReducer(), useEffect(), etc)
  • Use browser-only APIs
  • Use custom hooks that depend on state, effects, or browser-only APIs
  • Use React Class components

Best Practice

Moving Client Components to the Leaves

To improve the performance of your application, moving Client Components to the leaves of your component tree where possible. For example, you may have a Layout that has static elements (e.g. logo, links, etc) and an interactive search bar that uses state. Instead of making the whole layout a Client Component, move the interactive logic to a Client Component (e.g. SearchBar ) and keep your layout as a Server Component. This means you don't have to send all the component Javascript of the layout to the client.

Unsupported Pattern: Importing Server Components into Client Components

You cannot import a Server Component into a Client Component.

Recommended Pattern: Passing Server Components to Client Components as Props

A common pattern is to use the React children prop to create the "slot". We can refactor ExampleClientComponent to accept a generic children prop and move the import and explicit nesting of ExampleClientComponent up to a parent component.

This post is also on Medium

Source