radix-ui / primitives

Radix Primitives is an open-source UI component library for building high-quality, accessible design systems and web apps. Maintained by @workos.
https://radix-ui.com/primitives
MIT License
15.81k stars 821 forks source link

[Id] SSR – Mismatched server / client ids when running in `StrictMode` #811

Closed andy-hook closed 2 years ago

andy-hook commented 3 years ago

Related https://github.com/radix-ui/primitives/issues/793

Original report via Discord:

I'm trying to create a Dialog with IdProvider and I can't understand why SSR doesn't work, I got an error: Prop aria-controls did not match. Server: "radix-id-0-1" Client: "radix-id-0-4"

https://codesandbox.io/s/radixui-idprovider-ssr-mismatch-i3o1x

This is reproducible in our current SSR testing app since StrictMode was added in https://github.com/radix-ui/primitives/pull/795

Wrapping React.StrictMode or setting reactStrictMode: true in next.config is equivalent afaik.

andy-hook commented 3 years ago

Thought some more about this and then it struck me that of course this would be a problem, the implementation is proven non-deterministic in concurrent mode which is why StrictMode is having a cry about it and incrementing twice.

So then I thought about how might we solve for this and I kept ending up back in the same place – wouldn't it be easier to just not do this on the server in the first place? I did some digging and turns out Reach has been down this rabbit hole already and written a nice piece of documentation on it.

https://github.com/reach/reach-ui/blob/develop/packages/auto-id/src/index.tsx

While this is a warning and not a "today" problem, it will become a bigger issue in the future so the question is whether we'd want to take a similar approach here / now.

Worth noting that I did check in on other popular implementations and they suffer from the same issue.

csantos1113 commented 3 years ago

Any updates on this? We just ran into the same issue

andy-hook commented 3 years ago

Any updates on this?

Not since my follow up, one workaround is disabling StrictMode for now. The problem is only visible in development and production builds should behave as expected.

This issue isn't exclusive to Radix, it exists in many other id implementations in popular libraries. I need to speak with the team and see how we feel given the options available to us.

csantos1113 commented 3 years ago

This issue isn't exclusive to Radix, it exists in many other id implementations in popular libraries. I need to speak with the team and see how we feel given the options available to us.

Yeah, I created an issue in react-spectrum (https://github.com/adobe/react-spectrum/issues/2231) for react-aria to see how they react and what ideas they might have as well.

Thanks for the quick response @andy-hook - and yes, I did exactly that 😅 strictMode disabled for now

creeefs commented 3 years ago

Seeing the same issue as a NextJS user

julianbenegas commented 3 years ago

Any updates on this? It's a super annoying error 😅

espired commented 3 years ago

My logs gets filled up with this

andy-hook commented 3 years ago

I agree that this warning is not ideal but our options to resolve it without compromise are limited. In order to deal with this today we’d likely need to render id’s on the client only, this has performance and a11y consequences.

Once stable our best bet will be useOpaqueIdentifier. For now disabling StrictMode remains the best workaround 🙏

ashtonlance commented 3 years ago

So I've disabled StrictMode in next.config.js and I'm still getting the error. Anyone else?

andy-hook commented 3 years ago

So I've disabled StrictMode in next.config.js and I'm still getting the error. Anyone else?

@ashtonlance Have you tried upgrading all of your radix-ui packages to latest?

ashtonlance commented 3 years ago

I have. Everything is up-to-date including Stitches.

These are the UI packages I'm using.

"@radix-ui/react-accordion": "^0.1.0",
"@radix-ui/react-dialog": "^0.1.0",
"@radix-ui/react-icons": "^1.0.3",
"@radix-ui/react-id": "^0.1.0",
"@radix-ui/react-progress": "^0.1.0",
andy-hook commented 3 years ago

Strange 🤔 my only other suggestion is to try nuking node_modules and pinning all of the primitive packages at @0.1.1, we know of an issue where different versions between packages and react-id don't play nicely at the moment.

ashtonlance commented 3 years ago

@andy-hook tried that and still getting the same console errors.

andy-hook commented 3 years ago

@ashtonlance sorry to hear this, I can't reproduce on my end. Do you have a public project I could take a look at?

ashtonlance commented 3 years ago

@andy-hook I have a vercel staging url I can share! unless you need the source code -- that repo is private but I could add you as a user.

woshixixi commented 3 years ago

same issue here, bug with tooltip component

andy-hook commented 3 years ago

@andy-hook I have a vercel staging url I can share! unless you need the source code -- that repo is private but I could add you as a user.

@ashtonlance If you could add me that'd be great.

albingroen commented 3 years ago

Same issue for me, and I'm using the Dialog components.

ashtonlance commented 2 years ago

@andy-hook I have a vercel staging url I can share! unless you need the source code -- that repo is private but I could add you as a user.

@ashtonlance If you could add me that'd be great.

Added. Thanks for taking a look!

coderinblack08 commented 2 years ago

Possible react-18 solution? https://github.com/reactwg/react-18/discussions/111

jjenzz commented 2 years ago

@coderinblack08 Yep, that is the renamed useOpaqueIdentifier hook we mentioned. Looking forward to giving it a spin 💃

ajrussellaudio commented 2 years ago

For anyone late to the party dropping in from Google, not able to upgrade to React 18 yet, suppressHydrationWarning (docs) on the JSX element causing the warning worked for me.

jjenzz commented 2 years ago

@ajrussellaudio If you are able to upgrade to the latest versions of the primitives, the IdProvider is no longer needed and these warnings should all go away regardless of what React version you are on.

ajrussellaudio commented 2 years ago

Awesome @jjenzz thanks!

daniellizik commented 2 years ago

@ajrussellaudio how are you able to determine which elements require the suppresshydrationwarning flag? My terminal just spits out this message a bunch of times without any reference to where it originates from. i'm on react@17.0.2 and @radix/react-id@0.1.6

ajrussellaudio commented 2 years ago

@daniellizik By manual process of elimination, commenting out components until the error disappears and following the tree down.

But as @jjenzz points out, this fix is no longer needed if you upgrade your radix primitives dependency.

DennieMello commented 1 year ago

Problem reappeared, using react: 18.2.0, next: 13.4.12 with app router, @radix-ui/react-dialog.

Error: app-index.js:31 Warning: Prop aria-controls did not match. Server: "radix-:R16qcq:" Client: "radix-:R4r9j9:"

Any ideas for a fix besides setting a custom value in aria-controls?

joaom00 commented 1 year ago

@DennieMello Can you check if this is an issue on the Next.js side? https://github.com/radix-ui/primitives/issues/1684#issuecomment-1665811607

DennieMello commented 1 year ago

@DennieMello Can you check if this is an issue on the Next.js side? #1684 (comment)

Thanks, fixed in next: "13.4.13".