solidjs / solid-docs

SolidJS Docs.
https://docs.solidjs.com/
217 stars 248 forks source link

SSR hydration causes 'Failed attempt to create new DOM elements during hydration' #375

Closed asaf closed 7 months ago

asaf commented 11 months ago

Describe the bug

I'm trying to hydrate a component in the client but the following error occurs:

Uncaught (in promise) Error: Failed attempt to create new DOM elements during hydration. Check that the libraries you are using support hydration.
    at create (dev.js:124:37)
    at fn (dev.js:129:120)
    at dev.js:22:20
    at Hello (dev.js:25:7)
    at dev.js:552:12
    at untrack (dev.js:442:12)
    at Object.fn (dev.js:548:37)
    at runComputation (dev.js:698:22)
    at updateComputation (dev.js:681:3)
    at devComponent (dev.js:559:3)

Notes:

Best, Asaf.

Your Example Website or App

https://stackblitz.com/edit/github-xfquhi https://github.com/asaf/solidjs-ssr

Steps to Reproduce the Bug or Issue

  1. Clone repo https://github.com/asaf/solidjs-ssr
  2. pnpm i
  3. pnpm dev
  4. open browser http://localhost:3009/foo

Expected behavior

Component should be hydrated

Screenshots or Videos

No response

Platform

Additional context

No response

ryansolid commented 10 months ago

I'm glad the error is bringing more attention to this. It came my attention that many packages that thought they were hydrating were actually doing destructive client side rendering instead and users didn't realize it. This error indicates that the package isn't bundled correctly for SSR. We need write a better guide for this.

The problem is that Solid's compiler can output lots of different versions depending on settings you have and the compiler can change a bit version to version so generally I don't recommend libraries to precompile the JSX the way say a React library does. This is more like Svelte or Vue where we should ship the source code. I do encourage libraries to precompile the client build so people who us no build can use it, but anyone using SSR needs a server build and different client builds which complicated to push back on to the library maintainers.

So what look for is a solid export condition as a way of pointing at the source code (which I believe for vite might have to be a .jsx or .tsx extension). Generally I compile the TS out and just leave the JSX here but I don't know if many modern tools don't handle TS anyway.

We have a rollup preset that does this, but I think for a library like icons it is probably too simple of a setup to fit. https://github.com/solidjs-community/rollup-preset-solid

An example of the solid export can be found in a lot of our libraries like say solid router: https://github.com/solidjs/solid-router/blob/main/package.json#L21-L25

With this sort of setup you don't need to generate server builds and we rely on stuff like our Vite plugin to make sure the right builds are made for hydration etc..

I'm going to move this issue to docs to make sure this can be documented properly.

asaf commented 10 months ago

Thanks for answering,

Have you had a chance to look at my sample? I used tsup-preset-solid which is able to produce different client / server code and I have a node entry in the exports section and it also adds solid export condition.

Thanks.

LadyBluenotes commented 7 months ago

Consolidated this into #473