CSR

Client Side Rendering

The server sends a light shell. The browser does the data fetch and paints the real content.

Initial HTML

Browser

Initial Paint State

Empty shell, data loads after JS

Before hydration

Data in initial HTML

No

HTML generated by

Browser

User sees first

Loading state until hydration runs

Real-Time Rendering Timeline

Request to interactive UI

Performance API
1waiting

Request

Document request started

2waiting

HTML

HTML response received

3waiting

FCP

First contentful paint

4waiting

JS

Client JavaScript running

5waiting

Hydration

React effects can run

6waiting

Fetch

Client data request started

7waiting

Fetch done

Client data response resolved

8waiting

UI

React committed new data

Live Comparison

Production vs naive client updates

Same endpoint, same 3s cadence

TanStack Query

Production Pattern

Background Refetch
TanStack QueryCachedBackground Refetch
Preparing query state

Telemetry

Rendered at

Waiting for browser render

Data fetched at

Pending

Render source

Browser

Hydrated

No

Request count

0

Last update

Pending

Cache status

No cache

Update mode

Blocking fetch

useEffect Fetch

Naive Pattern

Client Fetching
useEffect FetchNo CacheClient Only
Local state is empty until fetch resolves

Telemetry

Rendered at

Waiting for browser render

Data fetched at

Pending

Render source

Browser

Hydrated

No

Request count

0

Last update

Pending

Cache status

No cache

Update mode

Blocking fetch

What to notice

Initial render

Initial render is browser-driven.

Production update

Cached + background refetch

Naive update

Initial loader + client fetch

Where HTML is generated

Browser

When

After JavaScript downloads and runs

Rendered at

Waiting for browser render

1Browser

Request page

The browser asks Next.js for /csr.

RUNNING / Document request
2Next.js Server

Send app shell

Next.js returns minimal HTML plus the client JavaScript bundle.

WAITING / HTML shell + JS
3Browser

Hydrate and run useEffect

React becomes interactive, then the client component starts fetching posts.

WAITING / JavaScript execution
4Data API

Fetch posts from browser

The network request happens after the page is already open.

WAITING / Client fetch
5Browser

Render final UI

React updates state, removes the loader, and paints the posts.

WAITING / No new HTML

Now happening

Browser: The browser asks Next.js for /csr.

Rendered at
Waiting for browser render
Data fetched at
Waiting for client fetch
Rendered on
Browser
Data source
English teaching dataset
Revalidate time
None

Behind the scenes

  1. Browser

    Request page

  2. Next.js Server

    Send app shell

  3. Browser

    Hydrate and run useEffect

  4. Data API

    Fetch posts from browser

  5. Browser

    Render final UI

Client component

The CSR demo uses a client component because useEffect and useState only run in the browser.

Loader is expected

The loader appears because data is not part of the first HTML response.

Live data stays separate

The live comparison updates after the app is interactive, independent of the initial render.