Describe the bug
When using the spread operator on an element that also has innerHTML defined a reactive update to the spread
object causes the element's content to be cleared if the app was hydrated from SSR. This does not happen when SSR is disabled or
when attributes are bound individually.
function App() {
const [count, setCount] = createSignal(0);
const [ref, setRef] = createSignal<HTMLDivElement>();
// Reactive object for spread
const data = createMemo(() => {
return {
"data-whatever": count() === 1 ? "yes" : "no",
};
});
onMount(() => {
console.log(ref()?.textContent); // Hello world! (Correct)
setCount(1);
setTimeout(() => {
console.log(ref()?.textContent); // "" (BUG: Should be "Hello world!")
console.log(ref()?.getAttribute("data-whatever")); // yes (Correct)
console.log(ref()?.getAttribute("class")); // flex (correct)
console.log(ref()?.getAttribute("style")); // color: red (Correct)
}, 500);
});
return (
<div
ref={setRef}
{...data()}
class="flex"
style="color: red"
innerHTML="Hello world!"
></div>
);
}
Your Example Website or App
https://stackblitz.com/github/youyoumu/solid-spread-hydration-bug
Steps to Reproduce the Bug or Issue
https://github.com/youyoumu/solid-spread-hydration-bug
- Clone the repo and install the dependency
- Run the dev server
- Open the dev server in browser and see the dom and the console.log ouput
- change
ssr to false on app.config.ts to confirm the bug only happen with ssr
Expected behavior
The innerHTML should remain intact when the spread object is updated, as long as the spread object does not contain a children or innerHTML key.
Actual Behavior
The element's content is cleared immediately upon the first reactive update of the spread object after hydration.
Screenshots or Videos
Picture of chrome dev tools showing div with data-whatever="yes" having no children/innerHTML

Picture of console output

Platform
- OS: Linux
- Browser: Chrome
- Version: 147.0.7727.116 (Official Build) (64-bit)
Additional context
- The bug only occurs when ssr: true. With ssr: false, it works as expected.
- If the attributes are bound individually (e.g.,
data-whatever={count() === 1 ? "yes" : "no"}) instead of using a spread, the bug does not occur.
Tested on
SolidJS + Vite
"dependencies": {
"@floating-ui/dom": "^1.7.6",
"solid-js": "^1.9.13"
},
SolidStart 1
"dependencies": {
"@solidjs/start": "1.3.2",
"solid-js": "^1.9.5",
"vinxi": "^0.5.7"
},
SolidStart 2
"dependencies": {
"@solidjs/start": "2.0.0-alpha.2",
"solid-js": "^1.9.5",
"vite": "^7.0.0",
"@solidjs/vite-plugin-nitro-2": "^0.1.0"
},
Describe the bug
When using the spread operator on an element that also has innerHTML defined a reactive update to the spread
object causes the element's content to be cleared if the app was hydrated from SSR. This does not happen when SSR is disabled or
when attributes are bound individually.
Your Example Website or App
https://stackblitz.com/github/youyoumu/solid-spread-hydration-bug
Steps to Reproduce the Bug or Issue
https://github.com/youyoumu/solid-spread-hydration-bug
ssrtofalseonapp.config.tsto confirm the bug only happen with ssrExpected behavior
The innerHTML should remain intact when the spread object is updated, as long as the spread object does not contain a children or innerHTML key.
Actual Behavior
The element's content is cleared immediately upon the first reactive update of the spread object after hydration.
Screenshots or Videos
Picture of chrome dev tools showing div with

data-whatever="yes"having no children/innerHTMLPicture of console output

Platform
Additional context
data-whatever={count() === 1 ? "yes" : "no"}) instead of using a spread, the bug does not occur.Tested on
SolidJS + Vite
SolidStart 1
SolidStart 2