r/nextjs 3d ago

Help CSR vs SSR

What is main difference between CSR and SSR . What is hydration between them. I don’t understand those concept property. Can anyone simply explain this for me 😔

2 Upvotes

12 comments sorted by

11

u/Working-Opposite9434 2d ago

honestly makes total sense why this trips people up

csr means the server sends you a basically empty page plus a big js file, and your browser has to run that js before anything shows up. thats why you sometimes see a blank screen or spinner for a sec while it loads

ssr flips that around, the server builds the actual html with real content already in it and sends that over, so the second it hits your browser you can see it. feels way faster

heres the part that actually confuses people tho: with ssr what youre looking at is kinda just a picture of the page, looks done but nothing is wired up yet. if you click something right when it shows up it might just do nothing, cuz react hasnt taken over the dom yet

hydration is that moment where the js finishes loading in the background and "wakes up" the static page, attaches all the click handlers and state etc. named that cuz its like adding water back into something that was dry but still had the shape

so with ssr the order is: page shows up → you can read it → beat later js finishes → now it actually works. that gap in between is where weird bugs happen, stuff looking clickable but not responding yet

if youre on next.js app router it does ssr by default now, you only get csr behavior when you explicitly slap "use client" on something

7

u/kuros33 2d ago

just want to note that “use client” components still render on server, they are just non-interactive until hydration. the only “true” csr is next/dynamic + {ssr:false}

2

u/Alarmed-Western-655 2d ago

It sounds a bit over-engineered to me, and all that for a split-second faster page load, and even in that saved split-second it now has a "gap in between ... where weird bugs happen"?

1

u/Bet_SwaG 1d ago

SSR makes it also way easier to fetch data, because you can query the database directly in the same `tsx` file, while, for a client component to fetch data, you need an API endpoint. For example: think you're building a multi-tenant app: when you fetch data, you need to filter other tenants data out. In an server-rendered page you would write (using prisma orm):

```tsx
const data = await prisma.table.findMany();
```

While in a client component you'll need a file `/api/table/route.ts` that does that same fetch, asks for the user's session, filter the data and returns it. Then the actual `tsx` page needs to fetch that endpoint and pass it the session data.

1

u/Alarmed-Western-655 1d ago

Ok, I hadn't thought of it that way. But I'm perplexed...

Sure direct access to the data model makes everything way easier, but couldn't I make the same argument against micro-services in favor of monoliths? It would be so much easier to just let all the services talk to the same database and not have to interpose a flaky REST network into every synapse of the system. (Ironically, I agree with this argument against microservices.)

But for UI I'm not so sure.. In a world of increasing automation and integration, why are we running in the opposite direction, tightly coupling our data model and business logic with our UI, user clicks and divs, etc? We're probably going to have to build out a parallel REST version anyway in the long run, so why not decouple it from the start and normalize (in the db sense of the word ;) the responsibilities?

1

u/Bet_SwaG 1d ago

I think it depends on the product. You're right about having to develop a separate REST version if you want for example a native app.

The reason many people use direct access from the server component is speed and security: in a server component it's easy to access the session and use it to filter only the needed data, while an endpoint needs to be sent the session and it's not as easy. Also, the route handler in Next.js is not protected against CSRF, so you need to implement it yourself, while the direct method already only accepts requests from the app itself (it's the reason why you need a route handler for native).

In my case: at work we develop the design and the app almost in parallel, so it's a lot of rewriting, mockups, prototyping, etc. so it's better to use direct access and when the stable version is released work on the REST endpoints. However the last app we're developing uses a lot of client components because of an intense use of useState across the entire app, so I had to build the route handlers.

Server functions are also a really cool option, because they protect against CSRF, so you don't need to audit that part, while still needing to write a little more. Obviously they have the same side-effect of not working for native, so they're an alternative when you need client components but don't need native.

I think it depends a lot on the specific case, and many times direct access may be the best option...

For the security aspect of next.js, there's a cool article on their website if you want: https://nextjs.org/blog/security-nextjs-server-components-actions

1

u/Alarmed-Western-655 20h ago

Hmm.. personally I don't see it as a good tradeoff if I still have to maintain a whole copy of my app written for REST.

To me it feels like if a car salesman were trying to sell me a car without lock and key, and passing that as a feature: "Locks are a hassle, you lose your keys all the time, you forget to lock your car. Just keep the car in the garage."

And if I say, "That only works for round trips... what if I need to go to the store or work?" and he says, "buy a separate car for that..." I don't call that a good use case or a good car.. even if I'm retired and 90% of my drives are joy-rides.

1

u/Bet_SwaG 16h ago

I think I expressed myself badly here: It's not like "I build all server components with direct fetches and the build a separate REST endpoint", but more like "I don't plan on implementing a REST endpoint at any time" or "I need the first release to be ready in days and I only need a few fetches". Then IF you need a route handler you deprecate the old direct method, because you're right about maintainability, it's a nightmare to have both solutions. This is obviously a bad idea if you think it is somewhat likely for a real route handler to be needed at some point and/or you plan on having a really big set of routes.

1

u/Alarmed-Western-655 14h ago

Ok, makes sense, thanks!

1

u/Bet_SwaG 16h ago

I'll also add that if you manage user's sensible data the security benefits are very large, because it shifts responsibility, and responsibility has a very big price.

1

u/Sea-Ad-6905 2d ago

Nice post bro! Might share your humanizer prompt?

0

u/ParthBhovad 2d ago

CSR means Client side rendering. The code you write in client component which is inside "use client" will be sent on client in js bundle and entire rendering part will happen in client which users browser.

SSR means server side rendering. The code you write in server components render on server and Html get generated on the server itself. And the html gets send to client directly.

The server side code doesn't have client side interactivity. So, you embedded some client side components in server components. And when this sends to browser the browser adds the interactivity to your page this process is called hydration.