โจ Introduction
Next.js gives you power to use Server Side Rendering (SSR) and Client Side Rendering (CSR) in the same project.
SSR gives fast ready pages. CSR gives interactive UI.
This blog explains both in a simple project using TypeScript.
๐ฅ๏ธ What is SSR
SSR means the server prepares HTML before sending the page.
This gives
- โก Fast first load
- ๐ Better SEO
- ๐ Ready content on first paint
Use SSR for content like posts products or anything you want visible right away.
๐งฉ What is CSR
CSR means the browser updates parts of the page after load.
Use CSR for
- ๐๏ธ Buttons
- ๐งฎ Counters
- โ๏ธ Forms
- ๐ Updating UI in real time
๐๏ธ How Next.js decides
- All components in App Router are server components by default
- Add
use clientat the top to make it a client component - Client components can use hooks like
useState - Server components cannot use hooks
- Client components cannot import server components
- Use
use serverfor server only logic like database work
๐ค When to use what
| Situation | Use |
|---|---|
| SEO and ready content | SSR |
| Interactive UI | CSR |
| Secrets or DB | Server code |
| Static pages | SSG |
๐ ๏ธ Small Next.js Project Example
We build one page
- Server component fetches posts
- Client component shows a counter
๐ Folder structure
my-next-app/
app/
page.tsx
components/
PostsList.tsx
Counter.tsx
actions.ts
package.json
tsconfig.json
๐ 1. Server Component Page
File: app/page.tsx
import PostsList from './components/PostsList'
import Counter from './components/Counter'
export default async function Page() {
return (
<main>
<h1>Server and Client Rendering Demo</h1>
<PostsList />
<hr />
<Counter />
</main>
)
}
๐ก Explanation
- This file is a Server Component
- It loads data on the server
- It imports a client component and renders both together
- HTML for posts is ready before load
๐ 2. Server Component for SSR
File: app/components/PostsList.tsx
async function fetchPosts() {
const res = await fetch('https://jsonplaceholder.typicode.com/posts')
return res.json()
}
export default async function PostsList() {
const posts = await fetchPosts()
return (
<ul>
{posts.slice(0, 5).map(post => (
<li key={post.id}>
<strong>{post.title}</strong>
<p>{post.body}</p>
</li>
))}
</ul>
)
}
๐ก Explanation
- No
use clientmeans it is server only - Data is fetched directly on the server
- Fast and SEO friendly
- The browser receives the ready HTML
๐ 3. Client Component for CSR
File: app/components/Counter.tsx
'use client'
import { useState } from 'react'
export default function Counter() {
const [count, setCount] = useState(0)
return (
<div>
<p>Count {count}</p>
<button onClick={() => setCount(c => c + 1)}>Add</button>
</div>
)
}
๐ก Explanation
-
use clienttells Next.js this runs in the browser - It uses
useStateso it must run on the client - The UI updates without page reload
๐ 4. Server Only Logic
File: app/actions.ts
'use server'
export async function addPost(data: { title: string; body: string }) {
// safe server side logic
return { ok: true }
}
๐ก Explanation
- Code stays on the server
- Good for DB or secret work
- Never sent to the browser
๐ 5. Pages Router SSR Example (optional)
File: pages/index.tsx
import type { GetServerSideProps } from 'next'
import { useState } from 'react'
export default function Home({ posts }) {
const [count, setCount] = useState(0)
return (
<main>
<h1>SSR with Pages Router</h1>
<ul>
{posts.map(p => (
<li key={p.id}>{p.title}</li>
))}
</ul>
<p>Local count {count}</p>
<button onClick={() => setCount(v => v + 1)}>Add</button>
</main>
)
}
export const getServerSideProps: GetServerSideProps = async () => {
const res = await fetch('https://jsonplaceholder.typicode.com/posts')
const posts = await res.json()
return { props: { posts: posts.slice(0, 5) } }
}
๐ก Explanation
-
getServerSidePropsruns on every request - Server returns the posts as props
- UI state still works with client hooks
๐งญ How to separate code correctly
โ Server code
- Use for API calls
- Use for DB logic
- No hooks
- Can fetch data safely
โ Client code
- For UI events
- For interactive features
- Needs
use client
โ Import rules
- Server can import client
- Client cannot import server
๐ Checklist
- Need SEO? โญ Server
- Need state or events? โญ Client
- Using secrets? โญ Server
- Want fast UI updates? โญ Client
๐ถ Step by step workflow
- Create a Next.js app
- Build server component for data
- Build client component for UI
- Combine them inside page
- Test SSR by turning off JS
- Test CSR by clicking the counter
- Improve step by step
โ FAQ
Q. Can server components use hooks?
No
Q. Can client components fetch data?
Yes
Q. Does server code ship to browser?
No
๐ Final Thoughts
- Next.js makes it simple to mix SSR and CSR in one project
- Use SSR for speed and SEO
- Use CSR for interaction
- Keep your code clean and split server and client logic
- You will build faster and better apps this way
Top comments (0)