You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When rendering React components in separate islands on one page, React's useId hook generates duplicate IDs.
The react useId hook generates incrementing IDs based on the react component tree. As islands have separate roots, they will generate their IDs separately, resulting in collisions.
Many accessibility-focused React UI libraries make use of useId to generate aria attributes. This functionality is currently not compatible with Astro.
React does provide a configuration option, identifierPrefix, which can be passed to createRoot, hydrateRoot, renderToString and similar functions.
If the react renderer adapter passed a unique identifierPrefix when rendering each island, this issue could be resolved.
I attempted adding this in to the react adapter, but I wasn't sure on the best method to generate a consistent unique ID per component during server rendering which could be accessible to client rendering.
At first I considered using the UID attribute on the astro-island wrapping element, unfortunately that isn't available at server render time, as it's generated from hashing the server renderinng response. This value also isn't guaranteed to be unique - if the same component is rendered in two places on a page with the same props, the generated UID is identical.
I'm not sure what the best solution would be, but I'd be more than happy to write up a PR if anyone has some better thoughts on how to achieve this!
I think the same method could work here. Use this.result which is a unique object for each render, and increment a counter. Then You can pass data attributes to use in the client.
Excellent, this seems like a more practical solution with fewer issues than serializing and hashing the props.
I'll work on porting the preact context solution over to the react adapter, and shall raise a PR if I get everything working. Thanks for pointing me in the right direction!
What version of
astro
are you using?2.2.3
Are you using an SSR adapter? If so, which one?
None
What package manager are you using?
pnpm
What operating system are you using?
Mac
What browser are you using?
Firefox
Describe the Bug
When rendering React components in separate islands on one page, React's
useId
hook generates duplicate IDs.The react
useId
hook generates incrementing IDs based on the react component tree. As islands have separate roots, they will generate their IDs separately, resulting in collisions.Many accessibility-focused React UI libraries make use of
useId
to generate aria attributes. This functionality is currently not compatible with Astro.React does provide a configuration option,
identifierPrefix
, which can be passed tocreateRoot
,hydrateRoot
,renderToString
and similar functions.If the react renderer adapter passed a unique
identifierPrefix
when rendering each island, this issue could be resolved.I attempted adding this in to the react adapter, but I wasn't sure on the best method to generate a consistent unique ID per component during server rendering which could be accessible to client rendering.
At first I considered using the UID attribute on the astro-island wrapping element, unfortunately that isn't available at server render time, as it's generated from hashing the server renderinng response. This value also isn't guaranteed to be unique - if the same component is rendered in two places on a page with the same props, the generated UID is identical.
I'm not sure what the best solution would be, but I'd be more than happy to write up a PR if anyone has some better thoughts on how to achieve this!
Link to Minimal Reproducible Example
https://stackblitz.com/edit/withastro-astro-lriyir?file=src/pages/index.astro
Participation
The text was updated successfully, but these errors were encountered: