diff --git a/.changeset/adopt-claim-scope-wire-id.md b/.changeset/adopt-claim-scope-wire-id.md new file mode 100644 index 000000000..9224fa8a0 --- /dev/null +++ b/.changeset/adopt-claim-scope-wire-id.md @@ -0,0 +1,5 @@ +--- +"@solidjs/web": patch +--- + +Thread the document wire id down as the adopted frame's claim scope. The identity split binds the frame to the call ADDRESS (function id + args hash), but the document producer stamps `_hk` hydration keys and region fids under the bare wire id — so every adopted claim on an args-bearing call (e.g. a note list keyed by search text) derived a `:hash`-suffixed prefix, missed the registry, and re-rendered fresh clones whose inserts moved the server-rendered `{$frame}` regions into a discarded detached tree: streamed content flashed and went blank. `claimScope` is the runtime's existing seam for exactly this (nested region frames already thread the root's scope down); adoptBoundary now passes the wire id through it. diff --git a/packages/solid-web/frames/src/client.ts b/packages/solid-web/frames/src/client.ts index 445a6ad9e..bf98449b0 100644 --- a/packages/solid-web/frames/src/client.ts +++ b/packages/solid-web/frames/src/client.ts @@ -689,7 +689,14 @@ function adoptBoundary( const hy = (globalThis as any)._$HY; return !!(hy && hy.fr && hy.fr.pending()); }, - drainRecords + drainRecords, + // The identity split binds the frame to the call ADDRESS (id + args + // hash), but the document producer stamped `_hk` keys and region fids + // under the wire name — the bare function id. Hydration-claim prefixes + // must derive from what the producer wrote, so thread the wire id down + // as the claim scope; without it every adopted claim misses and the + // occurrence re-renders fresh clones that cannibalize the server DOM. + claimScope: id } as {}) }); if (binding) followBinding(frame, binding);