new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

Next.js App Router · all subjects

app-router/server-client-components

25 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

Server and Client Components are used by default

Layouts and pages are Server Components by default in Next.js, which lets you fetch data and render parts of your UI on the server, optionally cache the result, and stream it to the client.

When to use Client Components

Use Client Components when you need: state and event handlers (onClick, onChange), lifecycle logic (useEffect), browser-only APIs (localStorage, window, Navigator.geolocation), or custom hooks.

When to use Server Components

Use Server Components when you need to: fetch data from databases or APIs close to the source, use API keys, tokens, and other secrets without exposing them to the client, reduce the amount of JavaScript sent to the browser, or improve First Contentful Paint (FCP) and stream content progressively to the client.

'use client' directive marks the Server-Client boundary

Adding 'use client' at the top of a file above imports declares a boundary between the Server and Client module graphs. All of its imports and the components it directly renders are included in the client bundle. You do not need to add the directive to every component intended for the client.

Client Component marker example

Create a Client Component by adding 'use client' at the top of the file: ```tsx 'use client' import { useState } from 'react' export default function Counter() { const [count, setCount] = useState(0) return ( <div> <p>{count} likes</p> <button onClick={() => setCount(count + 1)}>Click me</button> </div> ) } ```

Client-side rendering process on first load

On first load, the client: uses HTML to immediately show a fast non-interactive preview of the route, uses RSC Payload to reconcile the Client and Server Component trees, and uses JavaScript to hydrate Client Components and make the application interactive.

Subsequent navigations with RSC

On subsequent navigations: the RSC Payload is prefetched and cached for instant navigation, and Client Components are rendered entirely on the client without server-rendered HTML.

Module graph scope of 'use client'

The 'use client' directive applies to components that are part of the Client Component's module graph, which includes the modules it imports and the components it renders directly. It does not apply to Server Components passed as children or other props. Those components are not imported into the Client Component's module graph; they are rendered on the server and passed to the Client Component as rendered output.

Reduce JS bundle size by marking only interactive components

To reduce client JavaScript bundle size, add 'use client' to specific interactive components instead of marking large parts of your UI as Client Components. For example, if a layout contains mostly static elements like a logo and navigation links but includes an interactive search bar, mark only the Search component as a Client Component and keep the layout as a Server Component.

Pass data from Server to Client Components via props

You can pass data from Server Components to Client Components using props. Props passed to Client Components need to be serializable by React. Alternatively, you can stream data from a Server Component to a Client Component with the React 'use' API.

Interleave Server and Client Components using children

You can pass Server Components as a prop to a Client Component to visually nest server-rendered UI within Client components. A common pattern is to use 'children' to create a slot in a Client Component. For example, a Cart component that fetches data on the server can be passed as the child of a Modal component that uses client state to toggle visibility. Server Components passed as props are rendered on the server ahead of time, and the RSC Payload contains the rendered result plus placeholders for where Client Components should be rendered.

React context is not supported in Server Components

React context is commonly used to share global state but is not supported in Server Components. To use context, create a Client Component that accepts children, then import and use it in a Server Component (e.g. layout). Render providers as deep as possible in the tree to help Next.js optimize the static parts of your Server Components.

Context provider wrapper example

Create a Client Component context provider: ```tsx 'use client' import { createContext } from 'react' export const ThemeContext = createContext({}) export default function ThemeProvider({ children, }: { children: React.ReactNode }) { return <ThemeContext.Provider value="dark">{children}</ThemeContext.Provider> } ``` Then import it into a Server Component (e.g. layout): ```tsx import ThemeProvider from './theme-provider' export default function RootLayout({ children, }: { children: React.ReactNode }) { return ( <html> <body> <ThemeProvider>{children}</ThemeProvider> </body> </html> ) } ``` Server Components will be able to directly render the provider, and all Client Components throughout the app will be able to consume the context.

Wrap third-party client-only components

When using a third-party component that relies on client-only features (like useState), wrap it in a Client Component. For example, if the Carousel component from acme-carousel doesn't have 'use client' but uses client-only features, create a wrapper: ```tsx 'use client' import { Carousel } from 'acme-carousel' export default Carousel ``` Then use the wrapper directly in Server Components.

Library authors should add 'use client' to client-only entry points

If building a component library, add the 'use client' directive to entry points that rely on client-only features. This lets users import components into Server Components without needing to create wrappers. Some bundlers might strip out 'use client' directives, so configure your bundler if needed (e.g. esbuild).

Prevent environment poisoning with 'server-only' package

JavaScript modules can be shared between Server and Client Components, making it possible to accidentally import server-only code into the client. Use the 'server-only' package to prevent this. Import it at the top of files containing server-only code: ```js import 'server-only' export async function getData() { // server-only code } ``` If you try to import this module into a Client Component, there will be a build-time error. The 'client-only' package can similarly mark modules containing client-only logic.

Environment variables and client bundle

Only environment variables prefixed with NEXT_PUBLIC_ are included in the client bundle. If variables are not prefixed, Next.js replaces them with an empty string. This prevents accidental exposure of secrets like API_KEY to the client.

server-only and client-only installation

Installing 'server-only' or 'client-only' is optional in Next.js. However, if your linting rules flag extraneous dependencies, you may install them to avoid issues. Next.js handles 'server-only' and 'client-only' imports internally to provide clearer error messages. Next.js also provides its own type declarations for these packages for TypeScript configurations where noUncheckedSideEffectImports is active.

Server Component with async/await and data passing example

A Server Component can be async and fetch data, then pass it as props to a Client Component: ```tsx import LikeButton from '@/app/ui/like-button' import { getPost } from '@/lib/data' export default async function Page({ params, }: { params: Promise<{ id: string }> }) { const { id } = await params const post = await getPost(id) return ( <div> <main> <h1>{post.title}</h1> <LikeButton likes={post.likes} /> </main> </div> ) } ``` The LikeButton is a Client Component that receives the 'likes' prop from the Server Component.

Server Functions in Client Components import pattern

It is not possible to define Server Functions directly in Client Components. However, you can invoke them in Client Components by importing them from a file that has the 'use server' directive at the top of it.

Server Component Server Action inline definition

Server Functions can be inlined in Server Components by adding the 'use server' directive to the top of the function body. Server Components support progressive enhancement by default, meaning forms that call Server Actions will be submitted even if JavaScript hasn't loaded yet or is disabled.

Client Component form submission with Server Actions behavior

In Client Components, forms invoking Server Actions will queue submissions if JavaScript hasn't loaded yet, and will be prioritized for hydration. After hydration, the browser does not refresh on form submission.

Pass Server Actions as props to Client Components

You can pass a Server Action to a Client Component as a prop, allowing the Client Component to invoke it through form action or formAction properties.

Example: Server Action in Server Component inlined

This example shows how to define a Server Action inline within a Server Component: ```tsx export default function Page() { // Server Action async function createPost(formData: FormData) { 'use server' // ... } return <></> } ```

Example: Client Component importing and using Server Action

This example shows how to import a Server Action from a server file and use it in a Client Component: ```ts 'use server' export async function createPost() {} ``` ```tsx 'use client' import { createPost } from '@/app/actions' export function Button() { return <button formAction={createPost}>Create</button> } ```

Give your agent this brain