A CSR page in Next.js follows a lifecycle where the server delivers a minimal HTML shell, then JavaScript loads, executes, fetches data, and finally hydrates the page to become fully interactive
The lifecycle of a Client-Side Rendering (CSR) page in Next.js begins with the server delivering a minimal HTML skeleton, after which the browser takes over completely to render and make the page interactive. This approach prioritizes dynamic interactivity over initial content visibility, making it ideal for highly interactive applications like dashboards or authenticated experiences where SEO is less critical [citation:1][citation:5].
Browser requests the page URL from the Next.js server.
Server responds with a minimal HTML document containing a root div (e.g., <div id="__next"></div>) and script tags pointing to JavaScript bundles [citation:9].
No page content is present in the initial HTML — the user sees a blank screen or loading spinner if styled [citation:1][citation:3].
This phase is extremely fast due to minimal server processing, but provides no visible content yet [citation:9].
Upon receiving the HTML, the browser begins downloading the JavaScript bundles referenced in the script tags. These bundles contain the React application code, including components, logic, and data-fetching libraries [citation:5]. During this phase, the browser parses and executes the JavaScript, which can cause noticeable delay — especially on slower networks or devices [citation:3]. This is why CSR pages often have slower initial load times compared to SSR or SSG [citation:1].
After JavaScript executes, React renders the component tree for the first time. This initial render shows loading states, placeholders, or skeleton UI defined in the components [citation:5]. Immediately after this first render, useEffect hooks and data-fetching libraries like SWR or TanStack Query trigger API calls to fetch actual data [citation:1][citation:5]. During this period, the user sees loading indicators while data is being retrieved from backend services [citation:3].
When data fetching completes, the response data is stored in state (via useState) or cache (via SWR/TanStack Query) [citation:5]. This triggers a re-render of the component tree with the new data, replacing loading indicators with actual content. At this point, the page becomes fully populated with dynamic content [citation:1]. This re-render happens efficiently because React updates only the parts of the DOM that changed.
In a pure CSR page, "hydration" technically already happened during initial render because there was no server-rendered HTML to hydrate — the client built the DOM from scratch [citation:2][citation:6].
All event handlers (onClick, onChange, etc.) are attached during the initial render, so the page is interactive as soon as the first render completes [citation:9].
However, if data is still loading, interactive elements may not function as expected until their required data arrives [citation:1].
This differs from SSR/SSG pages where hydration is a separate step to attach handlers to pre-rendered HTML [citation:8].
After the initial load completes, the page operates entirely on the client. User interactions trigger state changes, which cause re-renders without additional server requests (unless fetching new data) [citation:3][citation:5]. Subsequent page transitions using Next.js Link component are fast because only necessary data is fetched, and JavaScript re-renders relevant parts without full page reloads [citation:5]. This is where CSR excels — providing smooth, app-like experiences after the initial load [citation:3].
SWR example with automatic caching and revalidation:
import useSWR from 'swr';
export function Page() {
const { data, error, isLoading } = useSWR('/api/data', fetcher);
if (error) return <p>Failed to load.</p>;
if (isLoading) return <p>Loading...</p>;
return <p>Your Data: {data}</p>;
}
``` [citation:5]
Benefits: automatic caching, deduplication, focus revalidation, and optimistic updates [citation:5].
TanStack Query provides similar capabilities with additional devtools and mutation utilities.
CSR in Next.js offers excellent interactivity and reduced server load but comes with significant trade-offs. Initial page load is slower because the browser must download, parse, and execute JavaScript before displaying content [citation:1][citation:3]. SEO is negatively impacted because search engine crawlers may not wait for JavaScript to execute and thus see empty or loading content [citation:5][citation:9]. However, for authenticated pages, dashboards, or highly interactive applications where SEO isn't a priority, CSR remains an excellent choice [citation:1]. Next.js promotes a hybrid approach where you can use CSR for some pages and SSR/SSG for others, depending on each page's requirements [citation:5][citation:7].