From 0f56d27960fe47a290fcb4840a7fc30a08aa5fef Mon Sep 17 00:00:00 2001 From: Brenley Dueck Date: Wed, 25 Feb 2026 20:34:35 -0600 Subject: [PATCH 1/8] chore: issue with fragment and props.children --- examples/ssr/shared/src/components/Home.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/ssr/shared/src/components/Home.js b/examples/ssr/shared/src/components/Home.js index 55bd3d68..0c02c00a 100644 --- a/examples/ssr/shared/src/components/Home.js +++ b/examples/ssr/shared/src/components/Home.js @@ -11,12 +11,16 @@ const Home = () => { }; }); return ( - <> +

Welcome to this Simple Routing Example

Click the links in the Navigation above to load different routes.

{s()} - +
); }; +function Wrapper(props) { + return <>{props.children}; +} + export default Home; From 509c1cdfa909e8719375b37bcf57e4b77d0916b8 Mon Sep 17 00:00:00 2001 From: Brenley Dueck Date: Thu, 26 Feb 2026 16:01:05 -0600 Subject: [PATCH 2/8] example with show --- examples/ssr/shared/src/components/Home.js | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/examples/ssr/shared/src/components/Home.js b/examples/ssr/shared/src/components/Home.js index 0c02c00a..c5d84da2 100644 --- a/examples/ssr/shared/src/components/Home.js +++ b/examples/ssr/shared/src/components/Home.js @@ -15,6 +15,7 @@ const Home = () => {

Welcome to this Simple Routing Example

Click the links in the Navigation above to load different routes.

{s()} + ); }; @@ -23,4 +24,18 @@ function Wrapper(props) { return <>{props.children}; } +function Counter() { + const [count, setCount] = createSignal(0); + return ( +
+ Too many clicks
}> +
+ {count()} + +
+ + + ); +} + export default Home; From 63c32ddcc956c732988ae702bba0b493b7fd7de2 Mon Sep 17 00:00:00 2001 From: Brenley Dueck Date: Fri, 27 Feb 2026 19:40:09 -0600 Subject: [PATCH 3/8] hydration --- examples/ssr/stream/rollup.config.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/ssr/stream/rollup.config.js b/examples/ssr/stream/rollup.config.js index 7a65bc03..ce60f09b 100644 --- a/examples/ssr/stream/rollup.config.js +++ b/examples/ssr/stream/rollup.config.js @@ -55,7 +55,7 @@ export default [ nodeResolve({ preferBuiltins: true, exportConditions: ["solid", "node"] }), babel({ babelHelpers: "bundled", - presets: [["solid", { generate: "ssr", hydratable: true }]] + presets: [["solid", { generate: "ssr", hydratable: true, dev: true }]] }), common() ] @@ -70,10 +70,10 @@ export default [ ], preserveEntrySignatures: false, plugins: [ - nodeResolve({ exportConditions: ["solid"] }), + nodeResolve({ exportConditions: ["solid", "development"] }), babel({ babelHelpers: "bundled", - presets: [["solid", { generate: "dom", hydratable: true }]] + presets: [["solid", { generate: "dom", hydratable: true, dev: true }]] }), common(), solidAssetManifest(), From 970f1b46e03223e178978d1232c5be8ef419f3a2 Mon Sep 17 00:00:00 2001 From: Brenley Dueck Date: Fri, 27 Feb 2026 23:25:06 -0600 Subject: [PATCH 4/8] ssr repros --- examples/ssr/shared/src/components/Home.js | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/examples/ssr/shared/src/components/Home.js b/examples/ssr/shared/src/components/Home.js index c5d84da2..cc437140 100644 --- a/examples/ssr/shared/src/components/Home.js +++ b/examples/ssr/shared/src/components/Home.js @@ -1,4 +1,4 @@ -import { createSignal, onSettled } from "solid-js"; +import { createSignal, Loading, onSettled } from "solid-js"; const Home = () => { const [s, set] = createSignal(0); onSettled(() => { @@ -12,10 +12,12 @@ const Home = () => { }); return ( -

Welcome to this Simple Routing Example

-

Click the links in the Navigation above to load different routes.

- {s()} - + +

Welcome to this Simple Routing Example

+

Click the links in the Navigation above to load different routes.

+ {s()} + +
); }; @@ -31,9 +33,12 @@ function Counter() { Too many clicks}>
{count()} - +
+ + + ); } From 1511d4a5e5558b63cbfffadf7fd461f82ad28ddd Mon Sep 17 00:00:00 2001 From: Brenley Dueck Date: Sat, 28 Feb 2026 10:17:15 -0600 Subject: [PATCH 5/8] Dynamic hydration problems --- examples/ssr/shared/src/components/Home.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/examples/ssr/shared/src/components/Home.js b/examples/ssr/shared/src/components/Home.js index cc437140..169b90bf 100644 --- a/examples/ssr/shared/src/components/Home.js +++ b/examples/ssr/shared/src/components/Home.js @@ -39,6 +39,9 @@ function Counter() { + + + ); } From 651b5da2427e798c584605dca17810ff2986b3e6 Mon Sep 17 00:00:00 2001 From: Brenley Dueck Date: Sat, 28 Feb 2026 18:57:40 -0600 Subject: [PATCH 6/8] Fix hydration errors --- examples/ssr/shared/src/components/Home.js | 48 ++++------------------ packages/solid-web/src/core.ts | 3 +- packages/solid/src/index.ts | 3 ++ packages/solid/src/server/core.ts | 9 ++++ packages/solid/src/server/flow.ts | 26 ++++++++---- packages/solid/src/server/hydration.ts | 3 ++ packages/solid/src/server/index.ts | 9 +++- 7 files changed, 52 insertions(+), 49 deletions(-) diff --git a/examples/ssr/shared/src/components/Home.js b/examples/ssr/shared/src/components/Home.js index 169b90bf..dffe3eee 100644 --- a/examples/ssr/shared/src/components/Home.js +++ b/examples/ssr/shared/src/components/Home.js @@ -1,49 +1,17 @@ -import { createSignal, Loading, onSettled } from "solid-js"; +import { createSignal, Errored, Loading, onSettled } from "solid-js"; const Home = () => { - const [s, set] = createSignal(0); - onSettled(() => { - const t = setInterval(() => { - const newVal = s() + 1; - set(newVal); - }, 100); - return () => { - clearInterval(t); - }; - }); - return ( - - -

Welcome to this Simple Routing Example

-

Click the links in the Navigation above to load different routes.

- {s()} - -
-
- ); -}; - -function Wrapper(props) { - return <>{props.children}; -} - -function Counter() { const [count, setCount] = createSignal(0); return (
- Too many clicks
}> -
- {count()} - -
+
{count()}
+ + + + + - - - - - - ); -} +}; export default Home; diff --git a/packages/solid-web/src/core.ts b/packages/solid-web/src/core.ts index ecfbca7b..fd49db84 100644 --- a/packages/solid-web/src/core.ts +++ b/packages/solid-web/src/core.ts @@ -11,7 +11,8 @@ export { merge as mergeProps, flatten, ssrHandleError, - ssrRunInScope + ssrRunInScope, + ssrConsumeId } from "solid-js"; export const memo = fn => createMemo(() => fn()); diff --git a/packages/solid/src/index.ts b/packages/solid/src/index.ts index 47e0b60c..2a595627 100644 --- a/packages/solid/src/index.ts +++ b/packages/solid/src/index.ts @@ -86,6 +86,9 @@ export { // stub export function ssrHandleError() {} export function ssrRunInScope() {} +export function ssrConsumeId(expr: any) { + return expr; +} import type { JSX } from "./jsx.js"; type JSXElement = JSX.Element; diff --git a/packages/solid/src/server/core.ts b/packages/solid/src/server/core.ts index e869c28f..4f53feb2 100644 --- a/packages/solid/src/server/core.ts +++ b/packages/solid/src/server/core.ts @@ -95,3 +95,12 @@ export function ssrRunInScope(fn: (() => any) | (() => any)[]): (() => any) | (( } return runWithOwner.bind(null, createOwner(), fn); } + +/** + * No-op identity function kept for API compatibility with dom-expressions. + * The ID matching for control flow components is now handled inside each + * component's server implementation (flow.ts / hydration.ts). + */ +export function ssrConsumeId(expr: T): T { + return expr; +} diff --git a/packages/solid/src/server/flow.ts b/packages/solid/src/server/flow.ts index 8ada441a..3f3ad231 100644 --- a/packages/solid/src/server/flow.ts +++ b/packages/solid/src/server/flow.ts @@ -23,11 +23,14 @@ export function For(props: { keyed?: boolean | ((item: T[number]) => any); children: (item: Accessor, index: Accessor) => U; }) { + const o = getOwner(); const options = "fallback" in props ? { keyed: props.keyed, fallback: () => props.fallback } : { keyed: props.keyed }; - return createMemo(mapArray(() => props.each, props.children, options)) as unknown as JSX.Element; + const result = createMemo(mapArray(() => props.each, props.children, options)); + if (o?.id != null) getNextChildId(o); // match client's insert() render effect when For is a sibling child + return result as unknown as JSX.Element; } /** @@ -41,14 +44,17 @@ export function Repeat(props: { fallback?: JSX.Element; children: ((index: number) => T) | T; }) { + const o = getOwner(); const options: { fallback?: Accessor; from?: Accessor } = "fallback" in props ? { fallback: () => props.fallback } : {}; options.from = () => props.from; - return repeat( + const result = repeat( () => props.count, index => (typeof props.children === "function" ? props.children(index) : props.children), options - ) as unknown as JSX.Element; + ); + if (o?.id != null) getNextChildId(o); // match client's insert() render effect when Repeat is a sibling child + return result as unknown as JSX.Element; } /** @@ -67,6 +73,7 @@ export function Show(props: { if (!props.keyed) getNextChildId(o); // match client's condition memo (non-keyed only) } const valueOwner = createOwner(); // match client's value memo + if (o?.id != null) getNextChildId(o); // match client's insert() render effect when Show is a sibling child return runWithOwner(valueOwner, () => { const when = props.when; if (when) { @@ -91,7 +98,7 @@ export function Switch(props: { fallback?: JSX.Element; children: JSX.Element }) const o = getOwner(); if (o?.id != null) getNextChildId(o); // advance ID counter - return createMemo(() => { + const result = createMemo(() => { let conds: MatchProps | MatchProps[] = chs() as any; if (!Array.isArray(conds)) conds = [conds]; @@ -103,7 +110,9 @@ export function Switch(props: { fallback?: JSX.Element; children: JSX.Element }) } } return props.fallback; - }) as unknown as JSX.Element; + }); + if (o?.id != null) getNextChildId(o); // match client's insert() render effect when Switch is a sibling child + return result as unknown as JSX.Element; } export type MatchProps = { @@ -128,11 +137,14 @@ export function Errored(props: { fallback: JSX.Element | ((err: any, reset: () => void) => JSX.Element); children: JSX.Element; }): JSX.Element { - return createErrorBoundary( + const o = getOwner(); + const result = createErrorBoundary( () => props.children, (err, reset) => { const f = props.fallback; return typeof f === "function" && f.length ? f(err, reset) : f; } - ) as unknown as JSX.Element; + ); + if (o?.id != null) getNextChildId(o); // match client's insert() render effect when Errored is a sibling child + return result as unknown as JSX.Element; } diff --git a/packages/solid/src/server/hydration.ts b/packages/solid/src/server/hydration.ts index 3af7c35a..67a6a084 100644 --- a/packages/solid/src/server/hydration.ts +++ b/packages/solid/src/server/hydration.ts @@ -1,5 +1,6 @@ import { createOwner, + getOwner, getNextChildId, runWithOwner, createLoadBoundary, @@ -49,9 +50,11 @@ export function Loading(props: { fallback?: JSX.Element; children: JSX.Element } ) as unknown as JSX.Element; } + const parent = getOwner(); const o = createOwner(); const id = o.id!; (o as any).id = id + "00"; // fake depth to match client's createLoadBoundary nesting + if (parent?.id != null) getNextChildId(parent); // match client's insert() render effect when Loading is a sibling child let runPromise: Promise | undefined; let serializeBuffer: [string, any, boolean?][] = []; diff --git a/packages/solid/src/server/index.ts b/packages/solid/src/server/index.ts index 7e5de8fd..ff9c9cd0 100644 --- a/packages/solid/src/server/index.ts +++ b/packages/solid/src/server/index.ts @@ -70,7 +70,14 @@ export type { } from "./signals.js"; // Wrappers — context, children, dev symbols -export { $DEVCOMP, children, createContext, useContext, ssrRunInScope } from "./core.js"; +export { + $DEVCOMP, + children, + createContext, + useContext, + ssrRunInScope, + ssrConsumeId +} from "./core.js"; export type { ChildrenReturn, Context, From 6fffab3a630bfa47a1d7463d6bef2294f77c4e7e Mon Sep 17 00:00:00 2001 From: Brenley Dueck Date: Sat, 28 Feb 2026 19:07:43 -0600 Subject: [PATCH 7/8] cleanup --- packages/solid-web/src/core.ts | 3 +-- packages/solid/src/index.ts | 7 ++----- packages/solid/src/server/core.ts | 9 --------- packages/solid/src/server/index.ts | 3 +-- 4 files changed, 4 insertions(+), 18 deletions(-) diff --git a/packages/solid-web/src/core.ts b/packages/solid-web/src/core.ts index fd49db84..ecfbca7b 100644 --- a/packages/solid-web/src/core.ts +++ b/packages/solid-web/src/core.ts @@ -11,8 +11,7 @@ export { merge as mergeProps, flatten, ssrHandleError, - ssrRunInScope, - ssrConsumeId + ssrRunInScope } from "solid-js"; export const memo = fn => createMemo(() => fn()); diff --git a/packages/solid/src/index.ts b/packages/solid/src/index.ts index 2a595627..6ff852fb 100644 --- a/packages/solid/src/index.ts +++ b/packages/solid/src/index.ts @@ -84,11 +84,8 @@ export { createOptimisticStore } from "./client/hydration.js"; // stub -export function ssrHandleError() {} -export function ssrRunInScope() {} -export function ssrConsumeId(expr: any) { - return expr; -} +export function ssrHandleError() { } +export function ssrRunInScope() { } import type { JSX } from "./jsx.js"; type JSXElement = JSX.Element; diff --git a/packages/solid/src/server/core.ts b/packages/solid/src/server/core.ts index 4f53feb2..e869c28f 100644 --- a/packages/solid/src/server/core.ts +++ b/packages/solid/src/server/core.ts @@ -95,12 +95,3 @@ export function ssrRunInScope(fn: (() => any) | (() => any)[]): (() => any) | (( } return runWithOwner.bind(null, createOwner(), fn); } - -/** - * No-op identity function kept for API compatibility with dom-expressions. - * The ID matching for control flow components is now handled inside each - * component's server implementation (flow.ts / hydration.ts). - */ -export function ssrConsumeId(expr: T): T { - return expr; -} diff --git a/packages/solid/src/server/index.ts b/packages/solid/src/server/index.ts index ff9c9cd0..b3471cfc 100644 --- a/packages/solid/src/server/index.ts +++ b/packages/solid/src/server/index.ts @@ -75,8 +75,7 @@ export { children, createContext, useContext, - ssrRunInScope, - ssrConsumeId + ssrRunInScope } from "./core.js"; export type { ChildrenReturn, From 7c37cbb01314164b5249ed9e476b0d6938c9a376 Mon Sep 17 00:00:00 2001 From: Brenley Dueck Date: Mon, 2 Mar 2026 11:36:26 -0600 Subject: [PATCH 8/8] Issue with spread --- examples/ssr/shared/src/components/Home.js | 25 ++++++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/examples/ssr/shared/src/components/Home.js b/examples/ssr/shared/src/components/Home.js index dffe3eee..2ab214f3 100644 --- a/examples/ssr/shared/src/components/Home.js +++ b/examples/ssr/shared/src/components/Home.js @@ -1,17 +1,28 @@ import { createSignal, Errored, Loading, onSettled } from "solid-js"; const Home = () => { const [count, setCount] = createSignal(0); + const props = { + test: "test", + test2: "test2" + }; return (
-
{count()}
- - - - - - + +
); }; +function Link(props) { + const linkProps = { + href: "/", + onClick: e => { + e.preventDefault(); + console.log("clicked", props.count); + } + }; + + return My Link {props.count}; +} + export default Home;