Skip to content

Catalyst/Link and next-intl/link composition issue caused by headlessui #1688

Closed
@plevik

Description

@plevik

What component?

  • Component name: Catalyst/Link

Describe the bug
If Link component is used as suggested in the docs integration section in plain Next.js all works great. But as soon as I try to replace next/link with next-intl/link I am getting following error headlessui error.

Error: Passing props on "Fragment"!

The current component <DataInteractive /> is rendering a "Fragment".
However we need to passthrough the following props:
  - ref
  - onFocus
  - onBlur
  - onPointerEnter
  - onPointerLeave
  - onPointerDown
  - onPointerUp
  - onClick
  - data-headlessui-state

You can apply a few solutions:
  - Add an `as="..."` prop, to ensure that we render an actual element instead of a "Fragment".
  - Render a single element as the child so that we can forward the props onto that element.

In the code I follow next-intl package instruction on how to compose the link component in the following manner, this is my current code failing solution:

import { Link as NextIntlLink } from '@/i18n/navigation';
import * as Headless from '@headlessui/react';
import React, { ComponentPropsWithoutRef, forwardRef } from 'react';

export const Link = forwardRef(function Link(
  props: ComponentPropsWithoutRef<typeof NextIntlLink>,
  ref: React.ForwardedRef<HTMLAnchorElement>
) {
  return (
    <Headless.DataInteractive>
      <NextIntlLink {...props} ref={ref} />
    </Headless.DataInteractive>
  );
});

Greatly appreciate any ideas on how to solve Headless.DataInteractive wrapper issue with next-intl/link component.

To Reproduce
Steps to reproduce the behavior:

  1. Set up fully working Next.js, Next Intl, Catalyst app
  2. Try to compose Catalyst/Link component with next-intl/link component that is comming from next-intl/create-navigation
  3. Open any application page where the link with href prop is rendered
  4. You should get the above error.

Expected behavior
I would expect it to work the same way as with next/link component, considering that next-intl/link is just a thin wrapper around

Additional context

  • Next.js 15 app router
  • React 19
  • headlessui/react 2.2.0
  • next-intl 4.0.2

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions