You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Universal renderer: lazy() automatically inserts an empty text node, which may or may not be supported by the underlying renderer #2283
upon upgrading, our proprietary universal render started to fail in cases where the lazy() element was being used, because we never implemented a version of createTextNode() that would intelligently handle the empty string the second half of that ternary.
Your Example Website or App
n/a
Steps to Reproduce the Bug or Issue
create a universal renderer, and implement createTextNode like so:
createTextNode: function(_text: string): MyNodeType{thrownewError("Text nodes not supported!")},
create an HTML with a lazy() component inserted.
Notice your error is triggered
Expected behavior
n/a
Screenshots or Videos
n/a
Platform
n/a
Additional context
So the reason we don't support bare text nodes in our renderer is that all of our text live inside a specific base element, like so:
<labeltext="my actual text"/>
so there was never a need to implement text nodes, and it would muddy the waters of our implementation to try. We can work around this issue just by ignoring bare text entirely. that said, if the implementation of a built in component tried to insert any other kind of text, for any reason, we'd still have this problem. One approach may just be to document this behavior, with wording along the lines of: "your renderer must at least support empty string and whitespace-only text nodes. your renderer may ignore them entirely if desired."
I see. Yeah we needed a fixed marker here. Empty text node seemed the easiest because it is mostly invisible in the DOM. We do this in things like Portals as well but I suppose you don't hit that in the universal renderer as well. Documenting it might be the easiest option I think. I'm not sure how else to best handle it.
Hey @ryansolid - I'm experiencing this issue as well.
I have a simple router with some pages that are loaded via Lazy. And this:
<View id="pageContainer" ref={pageContainer} forwardFocus={0} children={props.children} /> as the parent container.
With the Lazy there is an empty textNode being added to the pageContainer. However, when the page is created and added I now have the textNode and the childPage in the pageContainer children. It's not removing / replacing the empty text node when the first page is created. This is due to the page being a single top level node: <View /> - if its multi node (more than 1 child), the clean removes all children and everything is fine. When I switch pages, it replaces the empty text node with the new page, and now my pageContainer has newPage, oldPage as its children.
I'm using the Universal Renderer and just looking for advice on how to proceed. I'm going to try not allowing empty text nodes to be added as Children, but that may affect <Show> and other things...
MORE DETAILS:
The first element is a textNode (due to Lazy) and rather than replacing the second node its using the getFirstChild which is the textNode and thus leaving the previous page in the children
I'd like to take this one (Universal renderer: lazy()automatically inserts an empty). I'll look into the root cause and follow up with a PR. (claiming via @LeonxLJX)
I'd like to take this one (Universal renderer: lazy()automatically inserts an empty). I'll look into the root cause and follow up with a PR. (claiming via @LeonxLJX)
I'd like to take this one (Universal renderer: lazy()automatically inserts an empty). I'll dig into the root cause and follow up with a PR shortly. (claiming via @LeonxLJX)
Activity
ryansolid commentedon Sep 13, 2024
I see. Yeah we needed a fixed marker here. Empty text node seemed the easiest because it is mostly invisible in the DOM. We do this in things like Portals as well but I suppose you don't hit that in the universal renderer as well. Documenting it might be the easiest option I think. I'm not sure how else to best handle it.
chiefcll commentedon Dec 24, 2025
Hey @ryansolid - I'm experiencing this issue as well.
I have a simple router with some pages that are loaded via Lazy. And this:
<View id="pageContainer" ref={pageContainer} forwardFocus={0} children={props.children} />as the parent container.With the Lazy there is an empty textNode being added to the pageContainer. However, when the page is created and added I now have the textNode and the childPage in the pageContainer children. It's not removing / replacing the empty text node when the first page is created. This is due to the page being a single top level node:
<View />- if its multi node (more than 1 child), the clean removes all children and everything is fine. When I switch pages, it replaces the empty text node with the new page, and now my pageContainer has newPage, oldPage as its children.I'm using the Universal Renderer and just looking for advice on how to proceed. I'm going to try not allowing empty text nodes to be added as Children, but that may affect
<Show>and other things...MORE DETAILS:

The first element is a textNode (due to Lazy) and rather than replacing the second node its using the getFirstChild which is the textNode and thus leaving the previous page in the children
LeonxLJX commentedon Sep 1, 2026
I'd like to take this one (
Universal renderer:lazy()automatically inserts an empty). I'll look into the root cause and follow up with a PR. (claiming via @LeonxLJX)LeonxLJX commentedon Sep 1, 2026
I'd like to take this one (
Universal renderer:lazy()automatically inserts an empty). I'll look into the root cause and follow up with a PR. (claiming via @LeonxLJX)LeonxLJX commentedon Sep 1, 2026
I'd like to take this one (
Universal renderer:lazy()automatically inserts an empty). I'll dig into the root cause and follow up with a PR shortly. (claiming via @LeonxLJX)ryansolid commentedon Oct 13, 2026
Generated by Claude Code