Loading...
Loading...
Server Components are genuinely different from what came before. Here is a practical explanation.
React Server Components have been around in Next.js for a while now, and there is still a lot of confusion about what they actually do. I want to explain it without the "this changes everything" framing.
Before Server Components, if you had a page that needed data from a database, you had two main options:
getServerSideProps (in Next.js), pass data as props to your component tree.useEffect or a library like React Query.Both work, but option 1 puts the fetching logic outside your component tree, and option 2 means the client has to make a round trip after the initial render.
Server Components let you fetch data inside your components on the server, without those components ever shipping to the client. The component renders to HTML and RSC payload on the server, and that is it. No JavaScript for that component on the client.
If a component is a Server Component, the client never downloads the code for it. You can import a 200kb library in a Server Component and your client bundle does not grow. That is the bundle size benefit.
But Server Components cannot use browser APIs. No window, no document, no useState, no useEffect. They are just functions that run on the server and return JSX.
When you need interactivity, you mark a component with "use client". That component and everything it imports becomes a Client Component, which works the way React has always worked.
Client Components can render inside Server Components. Server Components cannot render inside Client Components (you can pass them as props/children, but you cannot import them).
This creates a mental model that takes some time to internalize. Your component tree can mix server and client components, but there is a boundary where the server side ends and the client side begins.
If you are using Next.js App Router, yes, because it is the default. You are already using Server Components whether you know it or not.
If you are on something else, it depends. The pattern is good for reducing client JavaScript, but the mental model adds complexity. For smaller apps, you might not need it.
The practical advice: learn where the server/client boundary is in your framework, understand why it exists, and you will stop being surprised by the errors.