Discover why mixing server and client code without rules can break your app--and how Next.js fixes it.
Why Server component restrictions in NextJS? - Purpose & Use Cases
Imagine building a web page where you manually fetch data on the server, then try to mix that with interactive buttons that need to run code in the browser.
You try to combine server-only code with client-side code all in one place.
This manual mix is confusing and error-prone because server code can't access browser features like clicks or animations.
Trying to run server code on the client or client code on the server causes bugs and slow loading.
Next.js server component restrictions clearly separate what runs on the server and what runs on the client.
This keeps data fetching and heavy work on the server, while interactive parts stay on the client, making apps faster and easier to build.
async function Page() {
const data = await fetchData();
return <button onClick={() => alert('Clicked!')}>Click me</button>;
}// page.tsx (Server Component)
export default async function Page() {
const data = await fetchData();
return <ClientButton />;
}
// ClientButton.tsx (Client Component)
'use client';
function ClientButton() {
return <button onClick={() => alert('Clicked!')}>Click me</button>;
}
export default ClientButton;This separation enables building fast, scalable apps that fetch data on the server and handle user interactions smoothly on the client.
Think of an online store page that loads product details from the server but lets you add items to the cart instantly without reloading the page.
Server components run only on the server and can fetch data securely.
Client components handle user interactions and run in the browser.
Restrictions keep these roles clear, avoiding bugs and improving performance.