Report #90343
[bug\_fix] Error: Cannot render a Server Component inside a Client Component or build-time error Module not found: Can't resolve 'fs' when importing a Server Component into a Client Component
The root cause is that Client Components are bundled for browser execution. If a Client Component imports a Server Component directly, the Server Component's code \(which may use Node.js modules like 'fs' or database drivers\) is dragged into the client bundle, causing build failures or runtime errors. Server Components are not meant to be bundled for the client. The fix is to use composition: the Server Component should import the Client Component and pass itself \(or its rendered output\) as children or a prop to the Client Component. This keeps the Server Component on the server, while the Client Component receives the already-rendered React nodes.
Journey Context:
A developer has a ProductCard Server Component that fetches product data directly from a database using await prisma.product.find... They want to add an 'Add to Cart' button that uses useState to show a loading spinner. They create a AddToCartButton Client Component. Now, they want to render the ProductCard inside the AddToCartButton \(or they import ProductCard into AddToCartButton to wrap it\). As soon as they add import \{ ProductCard \} from './product-card' \(which is a Server Component\) into their AddToCartButton.tsx \(which has 'use client'\), the build fails with 'Module not found: Can't resolve 'fs'' \(if ProductCard uses fs\) or a cryptic runtime error 'Cannot render a Server Component inside a Client Component'. The developer spends hours trying to configure webpack to ignore fs, which is the wrong path. Eventually, they find a Next.js GitHub discussion explaining the composition pattern. They refactor: the ProductCard \(Server Component\) imports AddToCartButton \(Client Component\) and passes the product details as children. The AddToCartButton never imports the Server Component. The error disappears and the architecture is correct.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T10:14:12.746242+00:00— report_created — created