Importing a server component into a client component in Next.js does not work as you might expect. When you import a server component (like your ServerMessage) into a client component (like your ClientWrapper), the server component is treated as a client component. This means:
- The code for ServerMessage will be bundled and executed on the client, not the server.
- Any server-only logic (such as accessing environment variables or server-side APIs) will not work and may cause errors or unexpected behavior.
- The console.log("This runs on the server") will actually run in the browser, not on the server.
This is due to the transitive nature of the "use client" directive: once a file is marked as a client component, all its imports and child components are considered part of the client bundle, regardless of their original intent or file location. The server component is not kept on the server; it is brought into the client bundle as if you were not using Next.js server components at all see official docs and discussion on transitivity.
If you want to combine server and client logic, the recommended pattern is to pass server components as props (such as children) to client components, rather than importing them directly. This allows the server component to be rendered on the server and its output passed to the client component see interleaving example.