Client-side rendering (CSR) means a component renders and fetches its own data entirely in the browser. Even in a Server Components-first framework like Next.js, CSR still has a legitimate role for specific, client-driven interactions.
When Rendering Genuinely Belongs on the Client
CSR happens naturally inside any Client Component that fetches its own data using useEffect (or a data-fetching library like SWR or TanStack Query) instead of receiving that data as props from a Server Component. This is appropriate when the data is inherently client-driven — it depends on user interaction, browser state, or needs to refresh independently of the page's initial load.
Unlike a traditional single-page app, where the entire page is CSR, a Next.js page typically stays mostly server-rendered, with CSR reserved for specific, self-contained widgets embedded inside it.
This widget polls for fresh data every ten seconds entirely in the browser — a natural fit for CSR, not something a Server Component could do on its own.
CSR Data Fetching Options
// Manual, with useEffect
useEffect(() => { fetch(url).then(...); }, []);
// With SWR (recommended for most client-side fetching)
import useSWR from "swr";
const { data, error, isLoading } = useSWR(url, fetcher);
useEffect + fetch works but requires you to manage loading/error state manually.
SWR and TanStack Query add caching, revalidation, and deduplication on top of client fetching.
CSR data is not included in the initial server-rendered HTML — it appears after hydration.
CSR content is generally not visible to search engine crawlers unless they execute JavaScript.
CSR Cheat Sheet
When CSR is (and isn't) the right tool.
Scenario
CSR Appropriate?
Initial page content for SEO
No — prefer Server Components
Live-updating widget (notifications, live counts)
Yes
Data that depends on client-only state (geolocation, local storage)
Yes
A form's submitted result immediately after posting
Sometimes — often better via Server Actions + revalidation
Third-party embedded widgets (maps, chat)
Often yes, by necessity
Using SWR for Cleaner Client Fetching
SWR ("stale-while-revalidate", from the Next.js team at Vercel) simplifies client-side fetching considerably, automatically handling caching, revalidation on focus/reconnect, and request deduplication.
Content rendered purely on the client is invisible to some crawlers and always arrives later than server-rendered HTML, which is precisely why Next.js defaults to Server Components — reserve CSR for content that genuinely doesn't need to be indexed or present in the very first paint.
Common Mistakes
Fetching a page's primary, SEO-relevant content on the client instead of in a Server Component.
Reimplementing caching and deduplication manually with useEffect instead of using SWR or TanStack Query.
Forgetting to clean up intervals/subscriptions in useEffect, causing memory leaks.
Treating CSR as the default rendering approach in a framework designed around Server Components first.
Key Takeaways
CSR still has a place in Next.js for client-driven, interactive, or frequently-polled data.
Client Components can fetch their own data via useEffect or libraries like SWR.
CSR content is not part of the initial server-rendered HTML and may be invisible to some crawlers.
Reserve CSR for widgets, not for a page's primary, SEO-relevant content.
SWR and TanStack Query handle caching and revalidation far more robustly than manual useEffect fetching.
Pro Tip
Before writing a useEffect-based fetch, ask whether the data could instead be fetched once on the server and passed down as a prop, with only genuinely live updates handled via a lightweight client-side polling or subscription layer on top of that initial value.
You now understand where CSR fits. Next, learn about streaming — how Next.js sends HTML to the browser progressively instead of all at once.