solid-start
solid-start copied to clipboard
[Bug?]: SSR / Hydration Mismatch for Ark UI + Panda CSS Project (Stackblitz example included)
Duplicates
- [X] I have searched the existing issues
Latest version
- [X] I have tested the latest version
Current behavior 😯
There is a working example of solid-start
+ Ark UI + Panda CSS provided in the Park UI lib here:
https://github.com/cschroeter/park-ui/tree/main/examples/panda/solid/solid-start
This project loads without issue both in stackblitz and also when I run the project locally.
When I make some minor modifications to include the ark ui datepicker component (with Panda CSS recipes) in this demo stackblitz, the project loads without issue.
Here is a live demo in Stackblitz: https://stackblitz.com/edit/github-ivec47?file=src%2Froutes%2Findex.tsx%3AL11,src%2Fcomponents%2Fui%2Fdate-picker.ts
Here is the forked source where I've introduced the change in my github fork https://github.com/brianfeister/park-ui/tree/solid-example-wip/examples/panda/solid/solid-start
The Stackblitz above works! (🎉 ) ... but when I run the same code locally, I get the following error:
Stepping through this in Chrome Debugger, I see the getNextElement()
function (in the erroring component) yielding a getHydrationKey()
of 0-0-0-0-0-0-0-0-0-1-0-0-0-0-0-1-0-0-2-0-0-1-0-0-0-0-2-0-2
but searching the DOM in the elements
tab yields no matching key in the DOM which seems suspect
Expected behavior 🤔
Cloning the repo https://github.com/brianfeister/park-ui/tree/solid-example-wip/examples/panda/solid/solid-start and running npm i && npm run dev
from this directory should execute successfully
Steps to reproduce 🕹
Steps:
-
git clone [email protected]:brianfeister/park-ui.git && git checkout solid-example-wip
-
cd park-ui/examples/panda/solid/solid-start && npm i && npm run dev
- Open
localhost:3000
- Hydration error ⚠️
Context 🔦
No response
Your environment 🌎
System:
Mac OS Sonoma 14.1.2
Dep Versions:
https://github.com/brianfeister/park-ui/blob/solid-example-wip/examples/panda/solid/solid-start/package.json
Thanks for taking the time to send the example. Unfortunately this was created with SolidStart's previous beta which we aren't continuing with. For that reason we need a new reproduction created with @solidjs/start 0.4.x or later.
There is an updated repro here.
https://stackblitz.com/edit/github-ivec47-zycscw
Instead of the error overlay, there is a blank screen, but the console does print a similar hydration error:
index.tsx:13 Error: Hydration Mismatch. Unable to find DOM nodes for hydration key: 0-0-0-0-0-0-0-0-1-0-0-0-0-0-0-3-0-0-1
at getNextElement (chunk-RW5WPR6J.js?v=8f61e8d3:272:37)
at index.tsx:6:3
at Home (index.tsx:13:28)
at @solid-refresh:25:42
at untrack (chunk-EI5OUS3E.js?v=8f61e8d3:443:12)
at HMRComp.createMemo.name [as fn] (@solid-refresh:25:28)
at runComputation (chunk-EI5OUS3E.js?v=8f61e8d3:707:22)
at updateComputation (chunk-EI5OUS3E.js?v=8f61e8d3:689:3)
at Object.readSignal (chunk-EI5OUS3E.js?v=8f61e8d3:625:67)
at resolveChildren (chunk-EI5OUS3E.js?v=8f61e8d3:1002:84
@ryansolid Is the repro here sufficient to demonstrate the bug? https://stackblitz.com/edit/github-ivec47-zycscw
(thanks @birkskyum!)
@ryansolid Is the repro here sufficient to demonstrate the bug? https://stackblitz.com/edit/github-ivec47-zycscw
(thanks @birkskyum!)
Yeah I think so. Issue is in the DatePickerDemo specifically. Probably related to prematurely rendering props that aren't inserted into the DOM. It's a lot to debug.. so starting by deleting until it works. But I think the issue is probably fairly high up.
EDIT: Yeah DatePicker.Root
with nothing else has a problem which makes me think the problem is in the HoC wrappers.
@ryansolid that makes sense, the HOC is where I traced the hydration mismatch to when digging deep into the solid js lifecycle internals. Specifically, there's the StyleContext.Provider
here
https://github.com/brianfeister/park-ui/blob/solid-example-wip/examples/panda/solid/solid-start/src/lib/create-style-context.tsx#L28
I'm brand new to Solid.js learning after many years of React. I might not be clear on the distinction between a React Provider and a Solid.js Provider... notably, I know the Solid reactivity model is different and doesn't follow the problematic virtual DOM pattern React does whereby changes to the application state model propagate to the top of the virtual DOM tree and then create a bunch of "ripples" as state iteratively settles
Sorry, not to get into theory, but just saying I'm not yet clear on the "way I solid.js provider should look and function". If I knew, I might be able to PR the fix for @cschroeter on https://github.com/cschroeter/park-ui
Bug report on Park UI repo: https://github.com/cschroeter/park-ui/issues/142
Well.. I'm still stripping stuff away. Trying to use just ArkDatePicker.Root
directly and still hitting issues. Which means now I want to look at how that's implemented. A lot of Solid libraries I realized recently aren't built properly for SSR. There could be Solid bugs in there as well. But I'm pretty sure it Ark-UI here. I see hydration IDs in the DOM around 6 and 10 where we are looking for 2. This suggests a bunch of siblings created prematurely.
Might be one for @segunadebayo (ark-ui) then... thanks! Fwiw, between solid-start + ark-UI + panda CSS, I'm super excited to do some greenfield work on a low-risk (but "real") project. Thanks for you hard work and dedication. 🙏
I tried to look into ArkUI. This is going to take a lot more time to look into then I have at the moment. The library is quite complex with layers of generalization going on here.
Understandable. Quick question on that... I know there's a Suspense component, but the Next.js 'use client' might be a good way forcing client side rendering specifically for components / libs that aren't written properly for SSR. Is that something that could play in here?
On Fri, Jan 5, 2024, 5:27 PM Ryan Carniato @.***> wrote:
I tried to look into ArkUI. This is going to take a lot more time to look into then I have at the moment. The library is quite complex with layers of generalization going on here.
— Reply to this email directly, view it on GitHub https://github.com/solidjs/solid-start/issues/1174#issuecomment-1879454302, or unsubscribe https://github.com/notifications/unsubscribe-auth/ALKYE5QZVBDK7RGTSC6VTY3YNCK5XAVCNFSM6AAAAABBACDRWOVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQNZZGQ2TIMZQGI . You are receiving this because you authored the thread.Message ID: @.***>
Thats different. We have a way to do browser only by setting ssr:false or by using clientOnly to isolate client only parts. use client
actually runs on both sides like SSR we do today. It's to differentiate from server components that never reach the browser.
Hi,
I'm having similar issues with Hydration Mismatch too in a very basic project. Here's the repo: https://github.com/alveshelio/solidstart-authjs-bun I'm using bun v1.0.22 and all my dependencies in the project are up to date. I've created a new page "Contact" and whenever I try to visit it, the first time I get a Not Found and if I do a refresh on the page I get the Hydration Mismatch error
This only happens when using bun
, if I use pnpm
then I don't get the Not Found nor the Hydration Mismatch error.
@alveshelio , thanks - i tried to reproduce this using bun, but I wasn't able to. I render the contact page alright with both bun run dev
and bun --bun run dev
. Can you tell more about your environment or make an online repro (like stackblitz or similar)?
Hello,
I'm having issues with Hydration Mismatch in my test project. Navigating to home page works OK, but if I reload page I get Hydration Mismatch error:
This is StackBlitz demo. Basically I use SuspenseList with 3 internal Suspense.
Hi I hit the same issue in a brand new project using v0.4.9. I reduced the code as much as possible trying to keep a reproducible version of the error and got to reproduce it with a simple div and a h1: https://github.com/danicruz0415/solidStartErrorExample
Its really strange, because I created two routes: /about/
and /auth/
, both look almost identical to me (the component is just a div and a title) but for some reason the first one works and the second one throws an error.
I restarted many times and ran npm run dev
again but the same thing happens.
I read about the issue and it says that it may be caused by components that have non-deterministic behavior, but I dont think that's the case because here its just a div
I attach screenshots of both, almost identical components, one of which fails, and the other one that works fine
Failing component
Component that works properly
As you can see, on the element that fails, on the browser inspector can be seen that the element has a data-hk="0-0-0-0-0-0-0-0-1-0-0-0-0-0-0-0-0-0-0-0"
but the error says that the hidration system is looking for the key 0-0-0-0-0-0-0-0-1-0-0-0-0-0-0-0-0-0-1
(last digit is different)
On the other hand on the element that works, the data-hk is the same, but it works fine. Both elements are under the same path so they don't have different layouts or anything. This is all the information I could gather on the issue. I hope it helps to find what the issue is.
@danicruz0415 thank you for the repro. I tried it locally, and inside of a stackblitz (link - i added a small menu), but I don't get any hydration error.
@birkskyum Its really strange, I cloned a brand new copy of my repo, and ran it locally and it worked fine. But I still have the folder with the files I uploaded and it still fails. I run git status
and it tells me there is no changes. I don't understand.
Maybe it could be caused by some files that remain during the build process? thus, when you download a new copy it works, but in my local previews version it fails because those files are not being regenerated properly? that's my best guess
I could try to see what files I can remove to make the issue go away and try to upload those files to the repo to see if this way you can replicate the error locally. Or I don't know if there is a way for me to enable more information to be shown, or a log error to be generated with more detail that could help figure out what's happening
Edit: I copied locally the folder of the project that failed (the full folder) and it worked just fine I ran again the original failing version and it still fails I am lost. Its the same folder copied, with all its packages and it behaves differently I don't know if there is any part of the compilation process that maybe caches some files or something and it links them to the project by the absolute path. As of now I have two identical copies of the project one works and one does not.
Edit 2 It happened to me again on another route, and I refreshed cache and it worked fine again, so maybe it has to do with some cached file
I am here for any information I can gather to help out. You let me know. In the meantime, if somebody is also experiencing this, it seems that cloning the repo in another folder resolves the issue.
@mikalaikabash @alveshelio maybe you can try this to see too, to see if it also makes the error go away for you
@birkskyum Its really strange, I cloned a brand new copy of my repo, and ran it locally and it worked fine. But I still have the folder with the files I uploaded and it still fails. I run
git status
and it tells me there is no changes. I don't understand.Maybe it could be caused by some files that remain during the build process? thus, when you download a new copy it works, but in my local previews version it fails because those files are not being regenerated properly? that's my best guess
I could try to see what files I can remove to make the issue go away and try to upload those files to the repo to see if this way you can replicate the error locally. Or I don't know if there is a way for me to enable more information to be shown, or a log error to be generated with more detail that could help figure out what's happening
Edit: I copied locally the folder of the project that failed (the full folder) and it worked just fine I ran again the original failing version and it still fails I am lost. Its the same folder copied, with all its packages and it behaves differently I don't know if there is any part of the compilation process that maybe caches some files or something and it links them to the project by the absolute path. As of now I have two identical copies of the project one works and one does not.
Edit 2 It happened to me again on another route, and I refreshed cache and it worked fine again, so maybe it has to do with some cached file
I am here for any information I can gather to help out. You let me know. In the meantime, if somebody is also experiencing this, it seems that cloning the repo in another folder resolves the issue.
@mikalaikabash @alveshelio maybe you can try this to see too, to see if it also makes the error go away for you
I tried running your code both locally and on stackblitz - it worked just fine
@danicruz0415 what versions do you use of package manager / node / os etc
Not sure if releated but I also had some strange errors using Solid.js app with Ad-Blockers enabled.
@birkskyum I have another example with SSR issue here: StackBlitz example
If you reload page 5-10 times eventually you get this error:
A lot of Solid libraries I realized recently aren't built properly for SSR
I'm having the same issue, can someone expand on what does it means practically to properly build a component for SSR? And why things like the following do not work?
return <>
<Show when={isServer} fallback="client">
server
</Show>
</>
(It writes "server" on the client page)
I think I finally cought it. This error had been hapenning here and there very inconsistently but I finally got to a case where I can reproduce the error 100% of the times. I think it has to do with how the SSR handles components inside of a route.
I created two routes. Both display a table using TankStank table The first one, I put the table directly into the function of the route, like so (simplified example):
export default function MyRoute(){
return <table>
<thead>
...
</thead>
</table>;
}
It worked perfecly, no matter how many times I reload or change routes. It works as expected ✅
Then I took the exact same code, and I put the table inside a component like so:
function MyTable() {
return <table>
<thead>
...
</thead>
</table>;
}
export default function MyRoute(){
return <MyTable />;
}
Then it works the first time, but as soon as I hard refresh (Shif + Ctrl + R in Chrome) It breaks ❌. 100% of the time. So its not about the library (In this case TankStank) because I used the same logic, same component and same everything. The issue happened as soon as I encapsulated the logic inside the route in a compontent. And it works fine when you enter the module for the first time, so the code works; if you navigate between routes it works well also. But as soon as you hard reload, it breaks (sometimes just with normal refresh as well).
So I append the step by step on how to reproduce the issue. I tested it myself with a brand new clone and it reproduced 100% of the times
- clone the example repository using
git clone https://github.com/danicruz0415/solidStartErrorExample.git
- enter the folder using
cd .\solidStartErrorExample\
, runnpm install
then runnpm run dev
- navigate to
http://localhost:3000/app/teachers/
- It will load fine.
- Then refresh using F5 or the browser icon until it breaks. It usually break at the first or at most second refresh. Note: this step is important, the error only happens after you refresh.
In the menu on the left you will see two options: "Teachers with bug" and "Teachers without bug". If you navigate between them using the menu, you will see that the error does not happen. If you go to "Teachers without bug", you will see that no matter how many times you refresh, the error does not occur. But if you go to "Teachers with bug" and refresh, it immediately breaks. Both pages are identical in content and logic, the only difference is that one returns the table directly (this one works) and the other one encapsulates the table inside a component (this one breaks)
I tried to eliminate as much code without losing the error, to have a shorter version. I hope this helps findind the cause and I hope with this example you can finally replicate the issue, as all previews examples sometimes failed and sometimes worked fine.
PS: I dont upload it to stackblitz, because all the examples posted by other people, when I run them it only shows "Upgrade Required". I don't know why. I read online that I only had to wait a bit, but It stays the same way for as much time I've left it that way.
Thank you so much for taking the time to look into this. I am tuned for any extra information that I may be able to recover. For now this is the information of my runtime:
Solid start version: 0.4.9
NPM version: 9.3.1
Vinxi version: 0.1.4
OS: Windows 11 (Version 10.0.22621 Build 22621)
Chrome version: Version 120.0.6099.217
Dependencies:
"@tanstack/solid-table": "^8.11.7" // for the table
"flowbite": "^2.2.1" // component library for styles (I don't think it affects)
"tailwindcss": "^3.3.3" // for styles
@danicruz0415 , excellent, I can confirm this reproduces the error as described, and my environment is quite different:
macos 4.2.1 arm64 / pnpm / firefox 119
A lot of Solid libraries I realized recently aren't built properly for SSR
I'm having the same issue, can someone expand on what does it means practically to properly build a component for SSR? And why things like the following do not work?
return <> <Show when={isServer} fallback="client"> server </Show> </>
(It writes "server" on the client page)
Think what this does. On the server it shows server
and when the client gets there it now doesn't. Which means that there is a hydration mismatch. It being undefined happens to be the way we handle defering the diff for stuff like lazy components, so it is getting past detection.
But before we get into how it fails we have to look at why. For things to hydrate the client needs to be in the same initial state as the server. So isServer
could never be used as a conditional in JSX. It could be used to say swap a data source or run code that only happens on server or client but it could never make a structure change to the DOM. If you want to show something extra in the client then you need to apply that change afterwards in an onMount
. Wanting something to only render on the server isn't as easy but also doesn't make a ton of sense (since it'd be immediately hidden).
Also @danicruz0415 thanks for the updated reproduction. I will take a look. It's quite possible these are different issues but any hydration issue is good to find.
It works fine on edge, but not chrome
chrome:
edge:
@GGBond0 have you tried it in Incognito mode? if it works then it has something to do with your extensions (most likely)
@GGBond0 have you tried it in Incognito mode? if it works then it has something to do with your extensions (most likely)
thank you, it worked fine in Incognito mode
@danicruz0415 , your reproduction ( https://github.com/danicruz0415/solidStartErrorExample ) breaks in the teachers
route because arrays are reference type. The columns array injected to the component through props gets two elements added every time the Table component initializes, so updating will show the columns array length grow as 3, 5, 7, 9 etc. In the working teachers2 route, because columns are defined outside component there will always be just the 3 expected columns.
function Table(){
let { data, columns } = props;
columns.unshift({ ... });
columns.push({ ... });
}
Breaking this connection, e.g. by making a new array like below will resolve the hydration error:
function Table(){
let { data, columns } = props;
columns = [...columns]; // <- Breaks the connection to the array outside the component
columns.unshift({ ... });
columns.push({ ... });
}
@GGBond0 have you tried it in Incognito mode? if it works then it has something to do with your extensions (most likely)
I just experienced a similar issue, I was getting these hydration errors even on a blank new page with no contents other than "Hello, World!". It worked fine in incognito, so I tried Ctrl+Shift+R on my non-incognito tab, and the error went away.
I know that's not a lot of information, I should have checked cookies/caches/etc. beforehand, but I wanted to let you know it worked for me. I will keep an eye out if I see the same error pop up again.