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

Update to version 1.7.18 of healessui/vue #41

Closed
gkkirilov opened this issue Feb 4, 2024 · 11 comments
Closed

Update to version 1.7.18 of healessui/vue #41

gkkirilov opened this issue Feb 4, 2024 · 11 comments

Comments

@gkkirilov
Copy link

HeadlessUI deployed a fix for Nuxt hydration error for generated ids.

Reference: tailwindlabs/headlessui#2913

@P4sca1
Copy link
Owner

P4sca1 commented Feb 5, 2024

This module uses ^1.0.0 syntax for the headless UI version, so that you can install whatever version you like and can update headless UI without updating this dependency. Just refresh your lock file, or install the latest version manually.

Remember that the fix requires you to add code to your app.vue file to provide the id generation function. This module can't do this for you due to limitations with the useId hook by nuxt.
Headless UI 2 will add this feature by default using Vue 3.5 builtin useId function.

@mwohlan
Copy link

mwohlan commented Feb 5, 2024

@P4sca1

I just made a reproduction because I still had mismatches after using the recommended fix. Turns out it only happens if I am using the Components through your module. Importing the components explicitly fixes the mismatches. You can easily check by un-commenting the imports.

https://stackblitz.com/edit/github-bbxtfw?file=app.vue

@simonmaass
Copy link

i can confirm this issue!

@P4sca1
Copy link
Owner

P4sca1 commented Feb 22, 2024

I can reproduce the issue, but did not yet find the reason for it. My guess right now is a symbol mismatch due to different imports, but I am not sure yet.
I will provide an update once I know more.

@P4sca1
Copy link
Owner

P4sca1 commented Feb 29, 2024

I invested a few hours today, but was unable to find out why this is not working.
For some reason the provided useId function is called on the server, but not on the client. So on the client the IDs are still generated using -i suffixes, leading to hydration mismatches.
I also tried calling provideUseId in a plugin added by this module without success.

@simonmaass
Copy link

@P4sca1 yeah i also could the in the DOM that the ids with the -i suffixe where generated

@gkkirilov
Copy link
Author

gkkirilov commented Mar 4, 2024

adding this to app.vue fixed it for me, at least until we get a proper fix

import { provideUseId } from '@headlessui/vue'

provideUseId(() => useId())

@lights0123
Copy link

lights0123 commented Mar 18, 2024

Looking at the network logs, it looks like my import statement within app.vue is fetching Headless UI from _nuxt/node_modules/.cache/vite/client/deps/@headlessui_vue.js—which is fully bundled—but the component from /_nuxt/node_modules/@headlessui/vue/dist/components/menu/menu.js. Therefore, there are two separate, incompatible copies of the library included. I also noticed a Vite log that it was "optimizing dependencies" when I added that line to app.vue for the first time.

To fix it, exclude the library from being optimized by Vite:

vite: {
    optimizeDeps: {
        exclude: ['@headlessui/vue'],
    },
},

It is my understanding that dependencies are not pre-bundled during production at all (i.e. this is a dev only problem), so this should have no performance or size impact on the final build.

@P4sca1
Copy link
Owner

P4sca1 commented Mar 19, 2024

Interesting find. Because there are 2 different bundles, the symbols that get injected likely don't match, which is causing the issue. Thank you for posting a workaround. I will check if it makes sense to include it by default.

@P4sca1
Copy link
Owner

P4sca1 commented Apr 4, 2024

This issue is likely related vitejs/vite#3910 and mentions the same workaround.

@P4sca1
Copy link
Owner

P4sca1 commented Apr 4, 2024

nuxt-headssui version 1.2.0 exposes a new provideHeadlessUseId composable, which should fix the issue.
Add the following to your app.vue file in <script setup> (everything is auto-imported):

// Use SSR-safe IDs for Headless UI
provideHeadlessUseId(() => useId())

@P4sca1 P4sca1 closed this as completed Apr 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants