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

Hydration mismatch for useId #25755

Closed
apinrdw opened this issue Feb 12, 2024 · 13 comments
Closed

Hydration mismatch for useId #25755

apinrdw opened this issue Feb 12, 2024 · 13 comments

Comments

@apinrdw
Copy link

apinrdw commented Feb 12, 2024

Environment

  • Operating System: Darwin
  • Node Version: v18.17.1
  • Nuxt Version: 3.10.1
  • CLI Version: 3.10.0
  • Nitro Version: 2.8.1
  • Package Manager: npm@9.6.7
  • Builder: -
  • User Config: nitro, devtools, experimental, runtimeConfig, components, app, css, modules, shadcn, tailwindcss, image, imports, build
  • Runtime Modules: nuxt-headlessui@1.1.5, nuxt-icon@0.5.0, @pinia/nuxt@0.5.1, @nuxt/image@1.3.0, @sidebase/nuxt-pdf@0.1.2, @nuxtjs/tailwindcss@6.11.4, shadcn-nuxt@0.8.7
  • Build Modules: -

Reproduction

Screenshot 2024-02-13 at 01 33 16

Describe the bug

I got this warn when fully reload the page that use useId composable.

Additional context

No response

Logs

No response

Copy link
Contributor

Would you be able to provide a reproduction? 🙏

More info

Why do I need to provide a reproduction?

Reproductions make it possible for us to triage and fix issues quickly with a relatively small team. It helps us discover the source of the problem, and also can reveal assumptions you or we might be making.

What will happen?

If you've provided a reproduction, we'll remove the label and try to reproduce the issue. If we can, we'll mark it as a bug and prioritize it based on its severity and how many people we think it might affect.

If needs reproduction labeled issues don't receive any substantial activity (e.g., new comments featuring a reproduction link), we'll close them. That's not because we don't care! At any point, feel free to comment with a reproduction and we'll reopen it.

How can I create a reproduction?

We have a couple of templates for starting with a minimal reproduction:

👉 https://stackblitz.com/github/nuxt/starter/tree/v3-stackblitz
👉 https://codesandbox.io/s/github/nuxt/starter/v3-codesandbox

A public GitHub repository is also perfect. 👌

Please ensure that the reproduction is as minimal as possible. See more details in our guide.

You might also find these other articles interesting and/or helpful:

@manchenkoff
Copy link

manchenkoff commented Feb 12, 2024

Same here 👍

<script lang="ts" setup>
// ...
const uniqueIdentifier = useId();
// ...
</script>

<template>
    <input
        :id="uniqueIdentifier"
        v-model="field"
        v-bind="$attrs"
    />
</template>

<style scoped></style>

This workaround helped, ofc as temp solution

const uniqueIdentifier = useId().replace(':', '_');

@daniluk4000
Copy link
Contributor

I've had that in my project when using client-only and fallback inside of it (needed to render empty input). Fixed by removing client-only and by relying on hydration end.

@gangsthub
Copy link
Contributor

gangsthub commented Feb 13, 2024

I have a reproduction link here, with @manchenkoff's suggestion:

https://stackblitz.com/edit/github-rq89e8?file=app.vue,components%2FTestId.vue

This way you don't get the hydration mismatch warning, but you still get the warning added here

[nuxt] `useId` is not compatible with components that have `inheritAttrs: false`.

@manniL, @danielroe are there any plans to support inheritAttrs: false in the future?

@danielroe
Copy link
Member

We need the ability to v-bind attrs to the root element as useId needs to access them when it hydrates.

@TheDutchCoder
Copy link
Contributor

We need the ability to v-bind attrs to the root element as useId needs to access them when it hydrates.

Why do you need them on the root element?

It's not uncommon to have custom form elements that have a wrapper div with input/label nested inside where you need the attrs to be bound to the input.

And even then, the attributes are still available (just not on the root element), no?

@danielroe
Copy link
Member

Why do you need them on the root element?

It is because of the mechanics of how we ensure a stable ID that matches between server and client. Of course there are other locations they could be stored, but how can the composable 'know' where to access them?

@jd1378
Copy link

jd1378 commented Feb 27, 2024

how can the composable 'know' where to access them?

maybe we can pass a ref of the element we use it on as an optional argument to the composable ?

@gregdev00
Copy link

I believe it's because of how the useId composable was implemented, it had different separators. It is fixed in this commit.

@gregdev00
Copy link

It is still producing this issue as of nuxt 3.11.0, the problem is that the return statement at the bottom of the packages/nuxt/src/app/composables/id.ts file has a different separator than the one specified at the top in a constant

const SEPARATOR = '-'
.
.
.
// this line needs to be changed to use SEPARATOR instead of the hardcoded _ character
return key + '_' + nuxtApp._id++ 

@manniL can you fix this as well please?

@manniL
Copy link
Member

manniL commented Mar 18, 2024

@gregdev00 no, see #26315

@madebyfabian
Copy link
Sponsor Collaborator

Can this be closed then?

@manniL manniL closed this as not planned Won't fix, can't repro, duplicate, stale Mar 29, 2024
@codeflorist
Copy link

codeflorist commented May 23, 2024

I'm still getting this error in various components (not all):

  - rendered on server: id="nnOfIU4QIk8-0"
  - expected on client: id="nnOfIU4QIk8_0"

There still seem to be cases, where a different seperator character is used (- vs _ ).

I think it happens in dynamically loaded components.

useId().replace('_', '-') is a workaround then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests