skip to Main Content

I’m using Next.JS 13.4.19 with the new app folder to enable React Server Components, and running into issues trying to use client sub-components (i.e. <ClientComponent.SubComponent >) inside a server component.

ClientTest.jsx is a Client component with sub-component attached (pretend this has some state or other reason to be client component)

'use client'

export default function ClientTest() {
  return <div>ClientTest</div>
}

ClientTest.Item = function ClientTestItem() {
  return <div>ClientTest.Item</div>
}

page.jsx is a React Server Component (allows access to db or file system)

import ClientTest from './ClientTest'

export default function Page() {
  // ClientTest.Item is undefined, and the following line errors with:
  // Unsupported Server Component type: undefined
  return (
    <ClientTest.Item />
  );
}

it seems the main component <ClientTest /> works fine, but the attached <ClientTest.Item /> is undefined 🙁

https://codesandbox.io/p/sandbox/currying-grass-wsvtn4?file=/app/page.tsx

Possible workaround would be to simply avoid sub-components in the server compoonent by making another wrapper client component (importing ClientTest.Item in a client component works fine) but I would greatly prefer if this could be fixed through some magic webpack configuration? or maybe it’s a bug in next.js?

For the record; Importing server sub-components in server components works fine, as does importing client sub-components in client components.

2

Answers


  1. The behavior you’re experiencing with Next.js server components is not a bug, but rather a limitation of the current implementation. Server components and client components have different scopes, and you cannot directly use client sub-components inside a server component due to these separate scopes.

    Server components and client components operate in different environments, and the server components are designed to run on the server and do not have access to the client-specific features, including client sub-components.

    As of my last knowledge; here was no official mechanism to directly import and use client sub-components within a server component.

    A possible workaround, as you mentioned, is to create an intermediary client component that wraps the client sub-component and use that intermediary component within your server component. This allows you to encapsulate the client-specific logic within the client component.

    You can try like this;

    'use client'
    
    export default function ClientTest() {
      return <div>ClientTest</div>
    }
    
    export function ClientTestItem() {
      return <div>ClientTest.Item</div>
    }
    

    And Page File;

    import { ClientTestItem } from 'yourfile';
    
    export default function Page() {
      return (
        <div>
          <ClientTestItem />
        </div>
      );
    }
    
    Login or Signup to reply.
  2. You do everything right, this is the Next.js problem. I just wrote a broad explanation of this behaviour. Please see
    https://stackoverflow.com/a/77077564/9047572

    TL:DR: you need that ‘use client’ directive to use client-only features. Once the component became client-side, its nested components are client-side too. No way to change or intercept this behavior.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search