nuxt-modules / supabase

Supabase module for Nuxt.
https://supabase.nuxtjs.org
MIT License
733 stars 129 forks source link

Hydration mismatch from cookie/localStorage mismatch #329

Open dts opened 9 months ago

dts commented 9 months ago

Version

@nuxtjs/supabase: 1.1.6 nuxt: 3.9.3

Reproduction Link

https://github.com/dts/supabase-nuxt-ssr-repro

Steps to reproduce

Add SUPABASE_URL and SUPABASE_KEY to .env, and start up the repro link above. Go to /erroring, type in email & password and log in. Then click the reproduce button. This clears the cookies but leaves the localStorage version in, and refreshes the page. You then see a hydration mismatch in the console.

What is Expected?

See /working, this uses an SSR-edge-case-aware layer on top of the useSupabaseUser composable, which defers the loading of the localStorage version of the user until after mounting. This causes a "flash", but no SSR errors. In this edge case, it's much better to have a flash than the indeterminate behavior of a SSR hydration mismatch, as the mismatch can leave the DOM in a bad state.

What is actually happening?

Because the Cookie & LocalStorage disagree about the state of the world, the browser and the server have different ideas of what is correct. This leads to a hydration mismatch. Mainly because the module is doing a great job of making sure all the authentication stuff is done as early as possible (probably a good thing for UX generally), this causes a hydration mismatch instead of a "flash". Hydration mismatches can be innocuous, but they can also give rise to very odd/incorrect DOM, which is what led me to start looking into this issue. (I have different layouts on / depending on whether the user is logged in or not.)