All questions

Best practice for choosing server-side vs client-side content rendering?

Asked by Paige Sutton on

PSPaige Sutton

I am standardizing a Next.js starter template for our agency and want to settle on a sensible default before we roll it out across client projects. Croct offers both fetchContent in server components and useContent in client components, and I would like to understand the concrete tradeoffs of each rather than picking one by habit.

Specifically: what does each choice cost in terms of rendering behavior, caching, and user experience? Is there a rule of thumb for when a slot belongs on the server versus the client?

Was this helpful?

2 answers

Ttk_ellis

The tradeoff is rendering mode versus flicker.

Server mode, fetchContent from @croct/plug-next/server, gives you no flicker and SEO-visible content: the HTML arrives already personalized. The cost is that it reads the request, which opts the route into dynamic rendering. That is the big one for a starter template. If a route is meant to stay static, do not call fetchContent on it, because you will silently lose static generation for that page.

Client mode, useContent in a 'use client' component, keeps the page static, but the content swaps in after load, which means flicker on the personalized slots. useContent relies on React Suspense, so wrap the component in a Suspense boundary with a sensible fallback, ideally something the same size as the final content to avoid layout shift.

My rule of thumb: above-the-fold and SEO-relevant slots go server-side and accept dynamic rendering; personalized widgets on otherwise static marketing pages go client-side.

Was this helpful?
ADAmina Diallo

One gotcha to bake into your template docs since your devs will move between both modes: the options shape differs. On the Next server side, evaluation attributes go under context, as in fetchContent('home-hero', {context: {attributes: {...}}}), while the React hooks take attributes at the top level. Easy to get wrong when copy-pasting a slot from a server component into a client one, and the failure is silent because the attributes just do not apply.

Was this helpful?
Still have questions?