-
Notifications
You must be signed in to change notification settings - Fork 1.4k
Description
Which component is affected?
Qwik Runtime
Describe the bug
I'm trying to work with containers to support microfrontend application, I'm using gioboa/qwik-microfrontends
approach (the the issue is here) gioboa/qwik-microfrontends#4 which relies on SSRStreamBlock
and SSRStream
component to fetch remote containers, but it doesn't work all the time (it works when it is rendered at the server only)
Reproduction
https://github.com/Karam2B/qwik_microfrontend_bug
Steps to reproduce
to replicate the error run pnpm dev
and visit localhost:12340
the resultant DOM is
<!-- does not work -->
<div q:shadowroot>
<template>...</template>
</div>
<!-- works -->
<div q:shadowroot q:key="...">
#shadow-root (open)
<template>...</template>
</div>
System Info
(node:32355) ExperimentalWarning: Support for loading ES Module in require() is an experimental feature and might change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
System:
OS: Linux 6.11 Ubuntu 24.04.2 LTS 24.04.2 LTS (Noble Numbat)
CPU: (16) x64 13th Gen Intel(R) Core(TM) i7-1360P
Memory: 9.47 GB / 15.31 GB
Container: Yes
Shell: 5.2.21 - /bin/bash
Binaries:
Node: 23.0.0 - ~/.nvm/versions/node/v23.0.0/bin/node
Yarn: 1.22.22 - ~/.nvm/versions/node/v23.0.0/bin/yarn
npm: 10.9.0 - ~/.nvm/versions/node/v23.0.0/bin/npm
pnpm: 9.12.2 - /usr/local/bin/pnpm
bun: 1.1.31 - ~/.bun/bin/bun
Additional Information
The bug is about qwik's containers, the bug can be found in following component ./host/src/routes/remote.tsx
export const Remote = component$(() => {
return <template shadowRootMode="open">
<SSRStreamBlock>
<SSRStream>{getSSRStreamFunction(remote.url)}</SSRStream>
</SSRStreamBlock>
</template>
});
the component works when it is rendered like this:
<Remote remote={{
name: "works",
url: "http://localhost:5174"
}} />
but doesn't work when is rendered like this
{
state.value.state === "browser_state" &&
<Remote remote={{
name: "does_not_work",
url: state.value.url
}} />
}
I think the bug is that SSRStreamBlock
or SSRStream
should be rendered at the server first to work, but my use case require the remote url to be only known at the client (otherwise I don't need containers/microfrontend, I would just have one big monolith)
my use case is an app that features plugins, where each plugin provide its own UI, and the information about where that UI is hosted is provided over HTTP request
export default component$(() => {
let state = useSignal<{ state: "server_state" } | { state: "browser_state", url: string }>({ state: "server_state" });
useVisibleTask$(() => {
// there might be auth wall before the following information is known
// it is only known at the client/browser
state.value = { state: "browser_state", url: "http://localhost:5174" }
})
return <div>
{state.value.state === "browser_state" &&
<Remote remote={{
name: "does_not_work",
url: state.value.url
}} />
}
<Remote remote={{
name: "works",
url: "http://localhost:5174"
}} />
</div >
})