Skip to content

React compiler breaks components that traverse immediate children #1105

Open

Description

@maxprilutskiy

Problem

The Lingo compiler breaks React components that traverse their immediate children (e.g., using React.Children.map or similar patterns). This happens because the compiler swaps JSX elements containing localizable text with LingoComponent instances, changing the component tree structure that parent components expect.

Example

When a parent component like a Tab container expects specific child components:

// Parent component expects Tab children
<TabContainer>
  <Tab>Home</Tab>
  <Tab>Settings</Tab>
</TabContainer>

// After Lingo compilation, structure changes:
<TabContainer>
  <LingoComponent ={...} ="..." ="..." />
  <LingoComponent ={...} ="..." ="..." />
</TabContainer>

The parent can no longer find its expected Tab children, breaking functionality.

Expected Behavior

The compiler should preserve the original component structure when transforming localizable text, ensuring parent-child relationships remain intact.

Possible Solution

One idea to consider: instead of swapping the component with LingoComponent while proxying props, the compiler could swap just the JSX text with a LingoChunk component (or similar) that returns either a string directly or a string wrapped in a Fragment (to avoid complicating the DOM).

Acceptance Criteria

  • Identify common React patterns that traverse immediate children (Tab containers, Accordions, etc.)
  • Implement compiler logic to preserve component tree structure during localization
  • Add test cases for components using React.Children APIs
  • Ensure transformed components maintain their original type/displayName for parent recognition

Activity

  1. github-actions commented on Aug 1, 2025

    @github-actions
    Contributor

    Claude finished @maxprilutskiy's task —— View job


    Issue Analysis and Triage âś…

    Completed comprehensive triage of the React compiler issue:

    • 1. Component identification - determined this relates to Compiler component
    • 2. Contributor analysis - returning contributor (30 previous issues)
    • 3. Codebase exploration - found relevant compiler code
    • 4. Issue intelligence - no duplicate issues found
    • 5. Applied appropriate labels - bug, compiler, enhancement
    • 6. Posted greeting comment
    • 7. Posted technical analysis - identified jsx-scope-inject.ts:136 as the root cause
    • 8. Posted team member tagging comment - tagged @mathio for compiler expertise
    • 9. Marked as autolabeled

    Technical Summary

    The issue is in packages/compiler/src/jsx-scope-inject.ts at line 136 where jsxScope.replaceWith(newNode) completely replaces JSX elements with LingoComponent instances. This breaks React components that use React.Children.map, React.Children.forEach, or similar APIs to traverse immediate children.

    The suggested solution to use a LingoChunk component for text-only replacement while preserving the original component structure is architecturally sound and would maintain parent-child relationships.

  2. github-actions commented on Aug 1, 2025

    @github-actions
    Contributor

    Hey @maxprilutskiy! Good to see you back. If you want to discuss this in real-time, we're always on Discord.

  3. github-actions commented on Aug 1, 2025

    @github-actions
    Contributor

    Based on the codebase, this affects jsx-scope-inject.ts in packages/compiler/src/jsx-scope-inject.ts around line 136. The compiler completely replaces JSX elements with LingoComponent instances using jsxScope.replaceWith(newNode), which breaks parent components that use React.Children.map or similar patterns to traverse their immediate children.

  4. github-actions commented on Aug 1, 2025

    @github-actions
    Contributor

    cc @mathio for CLI and compiler functionality

  5. anmolsah commented on Oct 29, 2025

    @anmolsah

    hey @maxprilutskiy , I’ve gone through this issue and the related compiler code in jsx-scope-inject.ts. I understand that replacing the entire JSX element with LingoComponent breaks parent-child traversal in React components. I’d like to work on this issue and contribute a fix that preserves the original component structure while still handling localization.

  6. codesmith17 commented on Oct 31, 2025

    @codesmith17

    hey @maxprilutskiy
    i've created a PR for this: #1476

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions