Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: Rewrite Rendering Section and React Essentials Page #51579

Merged
merged 74 commits into from
Aug 24, 2023
Merged
Show file tree
Hide file tree
Changes from 27 commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
8df9c9d
Recommend foundations course for beginners
delbaoliveira Jun 20, 2023
a21c723
Tentative outline
delbaoliveira Jun 20, 2023
85e4be8
Add RSC page intro
delbaoliveira Jun 20, 2023
3d02944
Merge branch 'canary' into docs-react-essentials-revamp
delbaoliveira Jun 20, 2023
cefc3a9
No code in page titles
delbaoliveira Jun 20, 2023
a2b145d
Merge branch 'canary' into docs-react-essentials-revamp
delbaoliveira Jul 6, 2023
b0c0d66
Brain dump: foundational concepts
delbaoliveira Jul 7, 2023
c060938
Merge branch 'canary' into docs-react-essentials-revamp
delbaoliveira Aug 1, 2023
e180bd0
Change of plans - remove react essentials pages
delbaoliveira Aug 1, 2023
58b9f39
Swap static/dynamic and components page
delbaoliveira Aug 1, 2023
acb9351
Write fundamentals introduction
delbaoliveira Aug 1, 2023
6aba8b8
Write about react rendering environments
delbaoliveira Aug 1, 2023
5e9ad99
Write about Next.js runtimes
delbaoliveira Aug 1, 2023
779a081
Write about rendering strategies
delbaoliveira Aug 1, 2023
1e153d6
Write about the request-response lifecycle
delbaoliveira Aug 1, 2023
4a2b148
Write about the network boundary
delbaoliveira Aug 1, 2023
bb23c01
Merge branch 'canary' into docs-react-essentials-revamp
delbaoliveira Aug 1, 2023
7d541ad
Merge branch 'canary' into docs-react-essentials-revamp
delbaoliveira Aug 2, 2023
d6de31d
Merge branch 'canary' into docs-react-essentials-revamp
delbaoliveira Aug 4, 2023
bfe05da
Move patterns to their own page
delbaoliveira Aug 4, 2023
48f5706
Clean and reshuffle
delbaoliveira Aug 4, 2023
60ded00
Review fundamentals
delbaoliveira Aug 4, 2023
f4da64a
Review fundamentals page
delbaoliveira Aug 7, 2023
d3b6073
hm, not quite there yet
delbaoliveira Aug 7, 2023
e371156
Write about the benefits / use cases for server rendering
delbaoliveira Aug 7, 2023
fa30c9d
Misc
delbaoliveira Aug 7, 2023
db453f1
Merge branch 'canary' into docs-react-essentials-revamp
delbaoliveira Aug 7, 2023
1f8ccc6
Write about using server components in Next.js
delbaoliveira Aug 8, 2023
f55e733
Update docs/02-app/01-building-your-application/03-rendering/index.mdx
delbaoliveira Aug 8, 2023
e857950
Move sections and delete React essentials page
delbaoliveira Aug 8, 2023
f8b2107
Write about building hybrid applications
delbaoliveira Aug 8, 2023
de081b6
Misc
delbaoliveira Aug 8, 2023
d39ce58
Write about how Server Components are rendered
delbaoliveira Aug 8, 2023
505e42a
Add note about data cache being separate from static rendering
delbaoliveira Aug 8, 2023
bccee54
Write client-side rendering outline
delbaoliveira Aug 8, 2023
a894cd6
Merge branch 'docs-react-essentials-revamp' of https://github.com/ver…
delbaoliveira Aug 8, 2023
225477c
Review
delbaoliveira Aug 9, 2023
7ca1f57
Write about streaming
delbaoliveira Aug 9, 2023
962a88c
Client rendering outline + use cases
delbaoliveira Aug 9, 2023
0f2d3a2
Write about "use client"
delbaoliveira Aug 11, 2023
51345c6
Discuss how client components are rendered for initial visit
delbaoliveira Aug 11, 2023
f58cf84
Write about switching back to the server environment
delbaoliveira Aug 11, 2023
5772dec
Update docs/02-app/01-building-your-application/03-rendering/02-clien…
delbaoliveira Aug 11, 2023
edd62b5
Rewrite composition patterns
delbaoliveira Aug 11, 2023
c35d708
Merge branch 'docs-react-essentials-revamp' of https://github.com/ver…
delbaoliveira Aug 11, 2023
013c765
Merge branch 'canary' into docs-react-essentials-revamp
delbaoliveira Aug 11, 2023
64c5ccf
Rename SSR and CSR pages
delbaoliveira Aug 17, 2023
b8c9e85
Rewrite Server Components page
delbaoliveira Aug 17, 2023
cbd9341
Rewrite Client Components page
delbaoliveira Aug 17, 2023
a3df58c
Review composition patterns page
delbaoliveira Aug 17, 2023
12acb6c
Fix some broken links
delbaoliveira Aug 17, 2023
bb0b589
Merge branch 'canary' into docs-react-essentials-revamp
delbaoliveira Aug 17, 2023
fd93a81
💅🏼
delbaoliveira Aug 17, 2023
842e1ec
Remove inaccurate information
delbaoliveira Aug 17, 2023
c2739f5
Fix some broken links
delbaoliveira Aug 17, 2023
6cbf13c
Merge branch 'canary' into docs-react-essentials-revamp
delbaoliveira Aug 17, 2023
d2514d3
Fix more broken links
delbaoliveira Aug 17, 2023
8c99b43
Merge branch 'docs-react-essentials-revamp' of https://github.com/ver…
delbaoliveira Aug 17, 2023
01b9205
Merge branch 'canary' into docs-react-essentials-revamp
delbaoliveira Aug 21, 2023
5362ef5
Update broken links
delbaoliveira Aug 21, 2023
1e9b673
More broken links
delbaoliveira Aug 21, 2023
37d6ce8
Review interleaving client and server components section
delbaoliveira Aug 21, 2023
a94e845
Merge branch 'canary' into docs-react-essentials-revamp
delbaoliveira Aug 21, 2023
bbdbbb9
Remove mention of Date not being serializable
delbaoliveira Aug 21, 2023
de1e03e
Merge branch 'docs-react-essentials-revamp' of https://github.com/ver…
delbaoliveira Aug 21, 2023
2a53544
Update docs/02-app/01-building-your-application/03-rendering/01-serve…
delbaoliveira Aug 21, 2023
a399b52
Apply suggestions from code review
delbaoliveira Aug 22, 2023
1c270ad
Update docs/02-app/01-building-your-application/03-rendering/03-compo…
delbaoliveira Aug 22, 2023
9dd27e0
Apply Michael's feedback
delbaoliveira Aug 23, 2023
8e4836d
Merge branch 'canary' into docs-react-essentials-revamp
delbaoliveira Aug 23, 2023
abff487
Update diagram placeholders
delbaoliveira Aug 24, 2023
92b9a87
Merge branch 'canary' into docs-react-essentials-revamp
delbaoliveira Aug 24, 2023
b768c89
Update broken link from merging into canary
delbaoliveira Aug 24, 2023
866cbcf
Merge branch 'canary' into docs-react-essentials-revamp
delbaoliveira Aug 24, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
261 changes: 0 additions & 261 deletions docs/01-getting-started/03-react-essentials.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,8 @@ title: React Essentials
description: An overview of essential React features for building Next.js Applications, including Server Components.
---

To build applications with Next.js, it helps to be familiar with React's newer features such as Server Components. This page will go through the differences between Server and Client Components, when to use them, and recommended patterns.

If you're new to React, we also recommend referring to the [React Docs](https://react.dev/learn). Here are some great resources for learning:

- [React Tutorial](https://react.dev/learn/tutorial-tic-tac-toe)
- [Thinking in React](https://react.dev/learn/thinking-in-react)
- [Learn React](https://react.dev/learn/describing-the-ui)

## Server Components

Server and Client Components allow developers to build applications that span the server and client, combining the rich interactivity of client-side apps with the improved performance of traditional server rendering.

### Thinking in Server Components

Similar to how React changed the way we think about building UIs, React Server Components introduce a new mental model for building hybrid applications that leverage the server and the client.

Instead of React rendering your whole application client-side (such as in the case of Single-Page Applications), React now gives you the flexibility to choose where to render your components based on their purpose.

For example, consider a [page](/docs/app/building-your-application/routing/pages-and-layouts#pages) in your application:

<Image
alt="Thinking in Server Components"
srcLight="/docs/light/thinking-in-server-components.png"
srcDark="/docs/dark/thinking-in-server-components.png"
width="1600"
height="652"
/>

If we were to split the page into smaller components, you'll notice that the majority of components are non-interactive and can be rendered on the server as Server Components. For smaller pieces of interactive UI, we can _sprinkle in_ Client Components. This aligns with Next.js server-first approach.

### Why Server Components?

So, you may be thinking, why Server Components? What are the advantages of using them over Client Components?

Server Components allow developers to better leverage server infrastructure. For example, you can move data fetching to the server, closer to your database, and keep large dependencies that previously would impact the client JavaScript bundle size on the server, leading to improved performance. Server Components make writing a React application feel similar to PHP or Ruby on Rails, but with the power and flexibility of React and the components model for templating UI.

With Server Components, the initial page load is faster, and the client-side JavaScript bundle size is reduced. The base client-side runtime is **cacheable** and **predictable** in size, and does _not_ increase as your application grows. Additional JavaScript is _only added_ as client-side interactivity is used in your application through [Client Components](#client-components).

When a route is loaded with Next.js, the initial HTML is rendered on the server. This HTML is then **progressively enhanced** in the browser, allowing the client to take over the application and add interactivity, by asynchronously loading the Next.js and React client-side runtime.

To make the transition to Server Components easier, all components inside the [App Router](/docs/app/building-your-application/routing#the-app-router) are Server Components by default, including [special files](/docs/app/building-your-application/routing#file-conventions) and [colocated components](/docs/app/building-your-application/routing#colocation). This allows you to automatically adopt them with no extra work, and achieve great performance out of the box. You can also optionally opt-in to Client Components using the ['use client' directive](#the-use-client-directive).

## Client Components

Client Components enable you to add client-side interactivity to your application. In Next.js, they are [pre-rendered](/docs/app/building-your-application/rendering) on the server and hydrated on the client. You can think of Client Components as how components in the [Pages Router](/docs/pages) have always worked.
Expand Down Expand Up @@ -126,227 +86,6 @@ This table summarizes the different use cases for Server and Client Components:

## Patterns

### Moving Client Components to the Leaves

To improve the performance of your application, we recommend 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.

```tsx filename="app/layout.tsx" switcher
// SearchBar is a Client Component
import SearchBar from './searchbar'
// Logo is a Server Component
import Logo from './logo'

// Layout is a Server Component by default
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<>
<nav>
<Logo />
<SearchBar />
</nav>
<main>{children}</main>
</>
)
}
```

```jsx filename="app/layout.js" switcher
// SearchBar is a Client Component
import SearchBar from './searchbar'
// Logo is a Server Component
import Logo from './logo'

// Layout is a Server Component by default
export default function Layout({ children }) {
return (
<>
<nav>
<Logo />
<SearchBar />
</nav>
<main>{children}</main>
</>
)
}
```

### Composing Client and Server Components

Server and Client Components can be combined in the same component tree.

Behind the scenes, React handles rendering as follows:

- On the server, React renders **all** Server Components **before** sending the result to the client.
- This includes Server Components nested inside Client Components.
- Client Components encountered during this stage are skipped.
- On the client, React renders Client Components and _slots in_ the rendered result of Server Components, merging the work done on the server and client.
- If any Server Components are nested inside a Client Component, their rendered content will be placed correctly within the Client Component.

> **Good to know**: In Next.js, during the initial page load, both the rendered result of Server Components from the above step and Client Components are [pre-rendered on the server as HTML](/docs/app/building-your-application/rendering) to produce a faster initial page load.

### Nesting Server Components inside Client Components

Given the rendering flow outlined above, there is a restriction around importing a Server Component into a Client Component, as this approach would require an additional server round trip.

#### Unsupported Pattern: Importing Server Components into Client Components

The following pattern is not supported. You cannot import a Server Component into a Client Component:

```tsx filename="app/example-client-component.tsx" switcher highlight={5,18}
'use client'

// This pattern will **not** work!
// You cannot import a Server Component into a Client Component.
import ExampleServerComponent from './example-server-component'

export default function ExampleClientComponent({
children,
}: {
children: React.ReactNode
}) {
const [count, setCount] = useState(0)

return (
<>
<button onClick={() => setCount(count + 1)}>{count}</button>

<ExampleServerComponent />
</>
)
}
```

```jsx filename="app/example-client-component.js" switcher highlight={5,14}
'use client'

// This pattern will **not** work!
// You cannot import a Server Component into a Client Component.
import ExampleServerComponent from './example-server-component'

export default function ExampleClientComponent({ children }) {
const [count, setCount] = useState(0)

return (
<>
<button onClick={() => setCount(count + 1)}>{count}</button>

<ExampleServerComponent />
</>
)
}
```

#### Recommended Pattern: Passing Server Components to Client Components as Props

Instead, when designing Client Components you can use React props to mark _"slots"_ for Server Components.

The Server Component will be rendered on the server, and when the Client Component is rendered on the client, the _"slot"_ will be filled in with the rendered result of the Server Component.

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.

```tsx filename="app/example-client-component.tsx" switcher highlight={6,16}
'use client'

import { useState } from 'react'

export default function ExampleClientComponent({
children,
}: {
children: React.ReactNode
}) {
const [count, setCount] = useState(0)

return (
<>
<button onClick={() => setCount(count + 1)}>{count}</button>

{children}
</>
)
}
```

```jsx filename="app/example-client-component.js" switcher highlight={5,12}
'use client'

import { useState } from 'react'

export default function ExampleClientComponent({ children }) {
const [count, setCount] = useState(0)

return (
<>
<button onClick={() => setCount(count + 1)}>{count}</button>

{children}
</>
)
}
```

Now, `<ExampleClientComponent>` has no knowledge of what `children` is. It doesn't know that `children` will eventually be filled in by the result of a Server Component.

The only responsibility `ExampleClientComponent` has is to decide where whatever `children` will eventually be placed.

In a parent Server Component, you can import both the `<ExampleClientComponent>` and `<ExampleServerComponent>` and pass `<ExampleServerComponent>` as a child of `<ExampleClientComponent>`:

```tsx filename="app/page.tsx" highlight={11} switcher
// This pattern works:
// You can pass a Server Component as a child or prop of a
// Client Component.
import ExampleClientComponent from './example-client-component'
import ExampleServerComponent from './example-server-component'

// Pages in Next.js are Server Components by default
export default function Page() {
return (
<ExampleClientComponent>
<ExampleServerComponent />
</ExampleClientComponent>
)
}
```

```jsx filename="app/page.js" highlight={11} switcher
// This pattern works:
// You can pass a Server Component as a child or prop of a
// Client Component.
import ExampleClientComponent from './example-client-component'
import ExampleServerComponent from './example-server-component'

// Pages in Next.js are Server Components by default
export default function Page() {
return (
<ExampleClientComponent>
<ExampleServerComponent />
</ExampleClientComponent>
)
}
```

With this approach, the rendering of `<ExampleClientComponent>` and `<ExampleServerComponent>` are decoupled and can be rendered independently - aligning with Server Components, which are rendered on the server before Client Components.

> **Good to know**
>
> - This pattern is **already applied** in [layouts and pages](/docs/app/building-your-application/routing/pages-and-layouts) with the `children` prop so you don't have to create an additional wrapper component.
> - Passing React components (JSX) to other components is not a new concept and has always been part of the React composition model.
> - This composition strategy works across Server and Client Components because the component that receives the prop has no knowledge of **what** the prop is. It is only responsible for where the thing that it is passed should be placed.
> - This allows the passed prop to be rendered independently, in this case, on the server, well before the Client Component is rendered on the client.
> - The very same strategy of "lifting content up" has been used to avoid state changes in a parent component re-rendering an imported nested child component.
> - You're not limited to the `children` prop. You can use any prop to pass JSX.

### Passing props from Server to Client Components (Serialization)

Props passed from the Server to Client Components need to be [serializable](https://developer.mozilla.org/en-US/docs/Glossary/Serialization). This means that values such as functions, Dates, etc, cannot be passed directly to Client Components.

> **Where is the Network Boundary?**
>
> In the App Router, the network boundary is between Server Components and Client Components. This is different from the Pages where the boundary is between `getStaticProps`/`getServerSideProps` and Page Components. Data fetched inside Server Components do not need to be serialized as it doesn't cross the network boundary unless it is passed to a Client Component. Learn more about [data fetching](/docs/app/building-your-application/data-fetching/patterns#fetching-data-on-the-server) with Server Components.

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

Since JavaScript modules can be shared between both Server and Client Components, it's possible for code that was only ever intended to be run on the server to sneak its way into the client.
Expand Down
8 changes: 0 additions & 8 deletions docs/01-getting-started/index.mdx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,22 +1,41 @@
---
title: Static and Dynamic Rendering
nav_title: Static and Dynamic
description: Learn about static and dynamic rendering in Next.js.
title: Server-Side Rendering
nav_title: Server-Side Rendering
description: Learn how Server-side Rendering works and its subsets - static and dynamic rendering.
related:
description: Learn how Next.js caches data and the result of static rendering.
links:
- app/building-your-application/caching
---

In Next.js, a route can be statically or dynamically rendered.
> In the beginning, there was the server. - _Copilot_

## Static Rendering (Default)
Server-Side Rendering is a strategy for rendering web applications on the server. In Next.js, this is done with [React Server Components](). The rendering work is further split into route segments to enable streaming.

This page will go through how Server Components work, when you might use them, and the three subsets of Server-Side Rendering:

- [Static Rendering](#static-rendering-default)
- [Dynamic Rendering](#dynamic-rendering)
- [Streaming](#streaming)

## React Server Components

React Server Components allow us to write UI that can be rendered and cached on the server. There are a couple of benefits to doing the rendering work to the server, including:

- **Data Fetching Performance**: Server Components allow you to move data fetching to the server, closer to your data source. This can improve performance by reducing the time it takes to fetch data and the amount of data sent over the network boundaries.
- **Security**: Server Components allow you to automatically keep sensitive data and logic on the server, such as environment variables, tokens, and API keys.
- **Rendering Performance**: By rendering on the server, the result can be cached and reused on subsequent requests and across users. This can improve performance by reducing the amount of work required to render a page.
- **User Experience**: Server Components allow you to keep large dependencies that previously would impact the client JavaScript bundle size on the server. This can be beneficial for users with slow internet connections or less powerful devices, as the work is done on the server instead of the client.
- **Initial Page Load and [First Contentful Paint (FCP)](https://web.dev/fcp/)**: On the server, we can use the RSC Payload to render HTML. This allows the page to be viewed immediately without waiting for JavaScript to download, parse, and execute on the client.
- **SEO Optimization**: Search engine bots can use the rendered HTML to crawl and index pages, this can improve your application's SEO.

## Using Server Components in Next.js

By default, Next.js statically renders routes to improve performance. At **build time**, Server and Client components are rendered on the server, and the result of the work is [cached](/docs/app/building-your-application/caching#full-route-cache) and reused on subsequent requests.

> To understand how Client and Server Components are rendered, see the [Rendering Client and Server Components](/docs/app/building-your-application/rendering/server-and-client-components) page.

## Dynamic Rendering
### Dynamic Rendering

With Dynamic Rendering, both Server _and_ Client Components for a route are rendered on the server at **request time**.

Expand All @@ -33,7 +52,7 @@ From the table above, for a route to be fully static, all data must be cached. H

> **Good to know**: In the future, Next.js will introduce hybrid server-side rendering where layouts and pages in a route can be independently statically or dynamically rendered, instead of the whole route.

### Dynamic Functions
#### Dynamic Functions

Dynamic functions rely on information that can only be known at request time such as a user's cookies, current requests headers, or the URL's search params. In Next.js, these dynamic functions are:

Expand All @@ -42,3 +61,5 @@ Dynamic functions rely on information that can only be known at request time suc
- In Client Components, it'll skip static rendering and instead render all Client Components up to the nearest parent Suspense boundary on the client.
- We recommend wrapping the Client Component that uses `useSearchParams()` in a `<Suspense/>` boundary. This will allow any Client Components above it to be statically rendered. [Example](/docs/app/api-reference/functions/use-search-params#static-rendering).
- **[`searchParams`](/docs/app/api-reference/file-conventions/page#searchparams-optional)**: Using the [Pages](/docs/app/api-reference/file-conventions/page) prop will opt the page into dynamic rendering at request time.

## Streaming

This file was deleted.

Loading