solidjs-community / solidjs-community/solid-primitives

`resize-observer@4.0.0-next.3` causes hydration mismatch

Open
#1,060 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
TypeScript
Stars
1.6k
Forks
162
Avg merge
19h 40m
Merged PRs (30d)
8

Description

Describe the bug
import { createSignal } from "solid-js";
import { createElementSize } from "@solid-primitives/resize-observer";

export default function ElementSizeHydrationRepro() {
  const [target, setTarget] = createSignal<HTMLDivElement>();
  const size = createElementSize(target);

  return <><div ref={setTarget}>Width: </div>{size.width ?? "waiting"}</>;
}

The cause is that createEffect advances hydration id but it's only created on the client:

https://github.com/solidjs-community/solid-primitives/blob/74ac166a63ccf7203aa4e6b0801f79ff7491aab3/packages/resize-observer/src/index.ts#L201

A workaround would be wrapping the use site in a new owner. A proper fix would be always createEffect regardless of isServer or not.

BTW, I believe that the idiomatic Solid2 way of writing this would be creating a writable signal with ssrSource: "client". This way the returned size can be non-null, but the result must be wrapped in a separate <Loading> boundary or else the component could never render due to the loop render -> get size -> observed el not mounted until rendered -> isPending, abort render. It sounds problematic at first but it actually prevents the render loop of using the size inside the measured element. However, that's a behavior change and needs discussion.

Minimal Reproduction Link

stack blitz pnpm is too old to run the new template

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in packages/resize-observer/src/index.ts around line 201, where createEffect is gated by isServer. Compare server and client hydration behavior using the provided ElementSizeHydrationRepro component. Done means the resize observer no longer causes a hydration mismatch while preserving the intended size behavior; the Solid2 behavior discussion may require separate clarification.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript
Domain
frontend
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
68/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.