Skip to content

[compiler] preserve JSXText HTML entity references during whitespace normalization#35974

Open
sleitor wants to merge 1 commit intofacebook:mainfrom
sleitor:fix-35971
Open

[compiler] preserve JSXText HTML entity references during whitespace normalization#35974
sleitor wants to merge 1 commit intofacebook:mainfrom
sleitor:fix-35971

Conversation

@sleitor
Copy link
Contributor

@sleitor sleitor commented Mar 7, 2026

Summary

Fixes #35971

HTML entity references such as   are decoded to their character value by Babel before the compiler sees the JSXText node. trimJsxText() normalises whitespace by checking for non-space/tab characters, so a node whose raw source was purely entity-encoded whitespace (e.g.  ) would be trimmed to null and silently dropped from the output.

Root Cause

Babel parses   as a JSXText node with value: ' ' (decoded space) and extra.raw: ' '. The trimJsxText function only sees the decoded value ' ', which contains no non-whitespace characters, so it returns null — causing the entity to be dropped.

Fix

When trimJsxText returns null for the decoded value, fall back to trimming the raw source text (exprPath.node.extra.raw). Since the raw form contains non-whitespace characters (&, #, digits, ;), trimJsxText(' ') returns ' ', which is emitted as a JSX string expression {" "} and decoded correctly by the standard JSX transform at runtime.

Test

Added a fixture jsx-html-entity-preserved that verifies   is preserved as {" "} in the compiled output. All 1720 existing compiler snapshot tests continue to pass.

…normalization

HTML entity references such as &facebook#32; are decoded to their character value by
Babel before the compiler sees the JSXText node. trimJsxText() normalises
whitespace by checking for non-space/tab characters, so a node whose raw source
was purely entity-encoded whitespace (e.g. '&facebook#32;') would be trimmed to null and
silently dropped from the output.

Fix: when trimJsxText returns null, fall back to trimming the raw source text
(exprPath.node.extra.raw). Because the raw form contains non-whitespace
characters ('&', '#', digits, ';'), trimJsxText('&facebook#32;') returns '&facebook#32;'
which is then emitted as a JSX string expression {"&facebook#32;"} and decoded
correctly by the standard JSX transform at runtime.

Fixes facebook#35971
@meta-cla meta-cla bot added the CLA Signed label Mar 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: React Compiler does not preserve HTML entity

1 participant