Error: Objects are not valid as a child. Encountered an object with the keys {0,1,2,3,4,5}.
in div (at [...]/test.jsx:7)
in Hello (at [...]/test.jsx:11)
at [...]/node_modules/preact/debug/dist/debug.js:1:6901
at Array.forEach (<anonymous>)
at n.options.diffed ([...]/node_modules/preact/debug/dist/debug.js:1:6796)
at o.options.diffed ([...]/node_modules/preact/hooks/dist/hooks.js:1:1497)
at [...]/node_modules/@preact/signals/dist/signals.js:1:1575
at j ([...]/node_modules/preact-render-to-string/dist/commonjs.js:1:7571)
at j ([...]/node_modules/preact-render-to-string/dist/commonjs.js:1:6493)
at Proxy.k ([...]/node_modules/preact-render-to-string/dist/commonjs.js:1:5029)
at render (test.jsx:11:24)
at Immediate.<anonymous> (file://[...]/test.vite.js:21:29)
There's only an error if a signal is not the only child of an element, e.g. <span>{mySignal}</span> works but <span>Hi {mySignal}</span> doesn't.
Minimal code to reproduce error, running on Node.js v18.9.0.
// server.js
import { on } from 'events'
import { Server } from 'http'
import { createServer as createViteServer } from 'vite'
const server = new Server()
const vite = await createViteServer({
server: { middlewareMode: true },
appType: 'custom'
})
server.listen(3000, async function () {
const res = await fetch('http://localhost:3000')
console.log(res.status, res.statusText, '\n', await res.text())
})
for await (const [req, res] of on(server, 'request')) {
vite.middlewares(req, res, async function () {
try {
const { render } = await vite.ssrLoadModule('./test.jsx')
const appHtml = await render()
res.statusCode = 200
res.setHeader('Content-Type', 'text/html')
res.end(appHtml)
} catch (err) {
vite.ssrFixStacktrace(err)
console.error(err)
res.statusCode = 500
res.end()
}
})
}
// test.jsx
import { default as renderToString } from 'preact-render-to-string'
import { signal } from '@preact/signals'
const name = signal('world')
function Hello() {
return <div>Hello {name}!</div>
}
export function render() {
return renderToString(<Hello />)
}
I also made sure that the preact-render-to-string package is not the culprit by running the following code through rollup:
// test.cjs
const render = require('preact-render-to-string')
const { signal } = require('@preact/signals')
const { h } = require('preact')
const name = signal('world')
function Hello() {
return <div>Hello {name}!</div>
}
console.log(render(<Hello />))
Using signals break vite SSR throwing the error:
There's only an error if a signal is not the only child of an element, e.g.
<span>{mySignal}</span>
works but<span>Hi {mySignal}</span>
doesn't.Minimal code to reproduce error, running on Node.js v18.9.0.
I also made sure that the
preact-render-to-string
package is not the culprit by running the following code through rollup: