The Next.js App Router executes React Server Components (RSC) on the server by default inside the app/ directory. Because server components never ship their code to the browser, your JavaScript bundle stays small and pages load faster.
You only opt into browser execution when a component needs state, effects, or user event listeners. Adding 'use client' at the top of a file marks the boundary between server and browser code.
flowchart TD
A["Incoming Request"] --> B["App Router Tree"]
B --> C["Server Component (Zero Browser JS)"]
C --> D["Client Component Leaf ('use client')"]
D --> E["Hydrated Interactive Button or Form"]
Keep data fetching, database queries, and heavy formatting libraries on the server. Move only interactive UI controls into Client Components.
'use client'): Use useState, useEffect, click handlers (onClick), or browser APIs like window and localStorage.Server Components can be async functions that await backend data directly before returning JSX.
// app/orders/page.tsx (Server Component)
import OrderFilterButton from './OrderFilterButton';
interface Order {
id: string;
total: number;
}
export default async function OrdersPage() {
const res = await fetch('https://api.example.com/orders', {
cache: 'no-store',
});
const orders: Order[] = await res.json();
return (
<section className="p-6 space-y-4">
<h2 className="text-2xl font-bold">Recent Orders ({orders.length})</h2>
<OrderFilterButton />
</section>
);
}
Place 'use client' as the very first line of interactive child components so the parent page stays on the server.
// app/orders/OrderFilterButton.tsx
'use client';
import { useState } from 'react';
export default function OrderFilterButton() {
const [onlyPaid, setOnlyPaid] = useState(false);
return (
<button
type="button"
onClick={() => setOnlyPaid((prev) => !prev)}
className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700"
>
{onlyPaid ? 'Showing Paid Orders' : 'Show Paid Only'}
</button>
);
}
'use client' at the top of layout.tsx: This forces every child page into the client bundle and blocks async server data fetching.fs into a 'use client' file.Yes, Next.js pre-renders Client Components into initial HTML on the server, then hydrates them in the browser so event handlers attach.
Yes, pass the Server Component as children or another prop from a parent Server Component rather than importing it directly into the client file.
'use client' need to go in every client child file?No, once a file has 'use client', any module it imports becomes part of the client bundle automatically.
Sign in to track your learning journey, earn industry-recognized certificates, and join our elite developer community.
Quick Access With
You've completed this section! Take a quick 5-question quiz to check your understanding.