Skip to main content
Back to Blog
1 min read

Server Components: the tradeoff that bit me

A short story about serialization boundaries, icon props, and how I debugged a Next.js error that had no stack trace.

next.jsreactdebugging

I converted a bunch of sections from client to server components on this very site to shave a few KB of JS off the initial load. The pattern looked fine — async component, await getTranslations(), done.

Then the build crashed with:

Functions cannot be passed directly to Client Components unless you explicitly expose it by marking it with "use server"

No file, no line number. The trick: a server component was passing icon components (which are functions) as props to a client component. React serializes props across the boundary, and you can't serialize a function.

The fix was small — have the server component render the icons as JSX (<CalendarIcon />) and pass them as ReactNode instead of passing the component reference. One line of surface change, but the mental model shift mattered: anything crossing server → client must be serializable JSON or serializable React elements.

Good reminder that "use server" and "use client" aren't just pragmas. They're a serialization boundary, and everything you put on props has to respect it.