Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Link component causing runtime error since upgrading to version 3.1+ #665

Closed
brandanking-decently opened this issue Nov 24, 2023 · 6 comments
Labels
bug Something isn't working unconfirmed Needs triage.

Comments

@brandanking-decently
Copy link

Description

Since upgrading to version 3.1.0+ the Link component generated by the createSharedPathnamesNavigation is providing the following error when the Link is inside a radix ui component that uses slots.

Error: Objects are not valid as a React child (found: object with keys {$$typeof, _payload, _init}). If you meant to render a collection of children, use an array instead.

This error didn't exist in the release candidates of the next-intl package.

Mandatory reproduction URL (CodeSandbox or GitHub repository)

https://codesandbox.io/p/devbox/next-intl-bug-template-app-forked-tl8gq7?file=%2Fsrc%2Fapp%2F%5Blocale%5D%2Fpage.tsx%3A15%2C53

Reproduction description

Steps to reproduce:

  1. Open reproduction
  2. Click on open button
  3. See error: Error: Objects are not valid as a React child (found: object with keys {$$typeof, _payload, _init}). If you meant to render a collection of children, use an array instead.

Expected behaviour

Revert next-intl to next-intl@3.0.0-rc.6 to see component working as expected

@brandanking-decently brandanking-decently added bug Something isn't working unconfirmed Needs triage. labels Nov 24, 2023
@amannn
Copy link
Owner

amannn commented Nov 25, 2023

This is an interesting case. In your case, Link renders as a Server Component—however, you're using <DropdownMenuItem asChild>, which expects a Client Component.

The fix depends on your app, but in the simplified demo, page.tsx can be marked with 'use client'; to fix this. It would probably also work to only wrap the respective DropdownMenuItem along with Link in a Client Component.

Hope this helps!

@amannn amannn closed this as completed Nov 25, 2023
@brandanking-decently
Copy link
Author

brandanking-decently commented Nov 27, 2023

This is an interesting case. In your case, Link renders as a Server Component—however, you're using <DropdownMenuItem asChild>, which expects a Client Component.

The fix depends on your app, but in the simplified demo, page.tsx can be marked with 'use client'; to fix this. It would probably also work to only wrap the respective DropdownMenuItem along with Link in a Client Component.

Hope this helps!

Hi, the asChild has no restrictions on whether the component is a client component or not, as if I just used the regular next/link component it works fine. Also it worked fine like this the the release candidates previously, it also works if I wrapped the Link component from next-intl in simple div tag.

As this broke during the release for RC to 3.1 release I'd expect this to have broken with some changes made in that last update

@sunxyw
Copy link

sunxyw commented Dec 10, 2023

any updates?

@stefvw93
Copy link

@amannn I think reopening this issue should be considered. Can confirm we are also experiencing this exact issue. We have a working Link in a radix ui Slot, in a project that uses the release candidate. The same pattern results in the error OP reported, when using the stable next-intl version. Regardless of client or server component implementation.

@stefvw93
Copy link

The same error occurs when directly using React Children api to process the Link, for example Children.count, Children.array all result in the invalid React child error.

@amannn
Copy link
Owner

amannn commented Feb 21, 2024

@stefvw93 I think there was a necessary change along the release candidate process where Link used to always be a Client Component, but now it's either a Server or Client Component, depending on where you import it from.

The issue is caused by the Radix asChild API, which is based on cloneElement—an API that only works for Client Components (more deatils here: #665 (comment)). I don't think this is something that next-intl can internally handle, but a restriction resulting from the React Server Components architecture.

Working example:

// LinkButton.tsx

import {Button} from '@radix-ui/themes';
import {Link} from '../navigation';

'use client';

export default function LinkButton({href, children}) {
  return (
    <Button asChild>
      <Link href={href}>{children}</Link>
    </Button>
  );
}
// page.tsx (a Server Component)

import {useTranslations} from 'next-intl';
import LinkButton from './LinkButton';

export default function IndexPage() {
  const t = useTranslations('IndexPage');
  return (
    <LinkButton href="/products">{t('products')}</LinkButton>
  );
}

Hope this helps!

outloudvi added a commit to outloudvi/info-pride that referenced this issue Mar 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working unconfirmed Needs triage.
Projects
None yet
Development

No branches or pull requests

4 participants