Skip to content

feat: solidjs integration#2510

Open
Huliiiiii wants to merge 13 commits into
lingui:mainfrom
Huliiiiii:solid
Open

feat: solidjs integration#2510
Huliiiiii wants to merge 13 commits into
lingui:mainfrom
Huliiiiii:solid

Conversation

@Huliiiiii

@Huliiiiii Huliiiiii commented Apr 13, 2026

Copy link
Copy Markdown

Description

  • Implemented @lingui/solid based on the @lingui/react design
  • Add the jsxRuntime option in @lingui/conf
  • Added solid-specific logic to babel-plugin-lingui-macro

Differences from React

  1. Components are compiled into:

    {
        0: (props) => <elm {...props}>
    }

    instead of:

    {
        0: <elm {...props}>
    }
  2. Reusing the same node multiple times in a translation string (for example, "<0/> <0/>") is not supported.

    For example, this source code:

    <Trans>
     Read the <a href="/docs">docs</a>.
    </Trans>

    produces a message like:
    Read the <0>docs</0>.

    A translation such as this is not supported:

    Read the <0>docs</0> or the <0>guide</0>.

    It will render as Read the or the <a href="/docs">guide</a>.

    This is because HTML elements cannot be cloned trivially. In this implementation, the same element is reused by reference instead of copies.

    The same limitation also applies when a JSX element stored in a variable is referenced multiple times.

    For example:

    const link = <a href="/docs">docs</a>
    
    <Trans>
      {link} or {link}
    </Trans>

    The output will be similar to:

    or <a href="/docs">docs</a>

    Using a component instead avoids this problem:

    const link = () => <a href="/docs">docs</a>

Types of changes

  • Bugfix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Examples update

Closes #2425

Checklist

  • I have read the CONTRIBUTING and CODE_OF_CONDUCT docs
  • I have added tests that prove my fix is effective or that my feature works
  • I have added the necessary documentation (if appropriate)

@vercel

vercel Bot commented Apr 13, 2026

Copy link
Copy Markdown

@Huliiiiii is attempting to deploy a commit to the Crowdin Team on Vercel.

A member of the Team first needs to authorize it.

@timofei-iatsenko

Copy link
Copy Markdown
Collaborator

@Huliiiiii please add description for the PR, with details:

  • What was implentend
  • What decision was taken
  • What decision considered but wasn't implemented
  • What the diffrences you had to implement to support solid.

That will make reviewing and merging the PR easier and faster. Thanks!

Comment on lines +205 to +210
["@lingui/react", "@lingui/solid"].some((moduleName) =>
path
.get("openingElement")
.get("name")
.referencesImport(moduleName, "Trans"),
)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Todo for myself: check if we can drop it entirely or make configurable. Don't want to have list of packages hardcoded

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Huliiiiii i think we can use macro.runtimeConfigModule.Trans option here and avoid hardcode, could you make it change and at a simple test testing that this property is respected? Thanks!

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Comment on lines +390 to +392
components: {
0: (props) => <a href="/docs" {...props} />,
},

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could you elaborate a bit onwhy this needed for Solid?

I wonder could we avoid branching and generate for both react and solid the same way? From the first glance it seems react would also work with no issues with this syntax

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

React uses VDOM, but Solid eagerly creates real DOM nodes. So preserve laziness manually is needed. Otherwise, for a component like this, there’s no correct way to insert children at the right position (using the approach in #2101).

const Comp = (props) => <div><div>before</div>{props.children}<div>after</div></div>

Maybe there’s a better solution, but I can’t think of one at the moment.

Comment thread packages/conf/src/__snapshots__/getConfig.test.ts.snap Outdated
Comment thread packages/solid/package.json
@Huliiiiii Huliiiiii force-pushed the solid branch 4 times, most recently from 43c18b7 to 4d5b385 Compare April 13, 2026 11:48
@Huliiiiii

Copy link
Copy Markdown
Author

I’ve updated the description.

Comment thread packages/babel-plugin-lingui-macro/test/jsx-trans.test.ts Outdated
@timofei-iatsenko

Copy link
Copy Markdown
Collaborator

Reusing the same node multiple times in a translation string (e.g. "<0/> <0/>") is not supported.
This is because html elements cannot be trivially cloned.

Could you elaborate on this? What this mean for a user? Could you write few examples what would work - what is not with possible workaround

@vercel

vercel Bot commented Apr 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
js-lingui Ready Ready Preview Jun 1, 2026 4:24pm

Request Review

@Huliiiiii

Copy link
Copy Markdown
Author

Reusing the same node multiple times in a translation string (e.g. "<0/> <0/>") is not supported.
This is because html elements cannot be trivially cloned.

Could you elaborate on this? What this mean for a user? Could you write few examples what would work - what is not with possible workaround

I've added some examples to the description. Would that be enough?

@timofei-iatsenko

timofei-iatsenko commented Apr 14, 2026

Copy link
Copy Markdown
Collaborator

@Huliiiiii

I've added some examples to the description. Would that be enough?

What happened with the following message?

<Trans>Hello <strong>user</strong> from planet <strong>Earth</strong>

Current macro will dedupe <strong> into one element like so:

{
    0: <strong>
}

Hello <0>user</0> from planet <0>Earth</0>

UPD:

I reread your description one more time, and it seems i didn't get it correctly. Correct me if'm wrong - this issue you described

Reusing the same node multiple times in a translation string (for example, "<0/> <0/>") is not supported.

You already solved with () => <jsx> syntax, so it's supported correctly, right?

@Huliiiiii

Huliiiiii commented Apr 14, 2026

Copy link
Copy Markdown
Author

@Huliiiiii

I've added some examples to the description. Would that be enough?

What happened with the following message?

<Trans>Hello <strong>user</strong> from planet <strong>Earth</strong>

Current macro will dedupe \<strong\> into one element like so:

{
    0: <strong>
}

Hello <0>user</0> from planet <0>Earth</0>

UPD:

I reread your description one more time, and it seems i didn't get it correctly. Correct me if'm wrong - this issue you described

Reusing the same node multiple times in a translation string (for example, "<0/> <0/>") is not supported.

You already solved with () => <jsx> syntax, so it's supported correctly, right?

() => <jsx> will create a new instance.

Deduplication should works correctly if the current tests already cover that.

The core difference is that solid can only use references, but react uses clones/copies.

@Huliiiiii

Copy link
Copy Markdown
Author

Tests failed because @babel/plugin-syntax-jsx is missing. Should I fix this in this PR as well?

@andrii-bodnar

Copy link
Copy Markdown
Contributor

@Huliiiiii thank you for the contribution!

Improving Lingui's compatibility with SolidJS and the broader ecosystem (Astro, Vue, Svelte) is a major focus for the community at the moment.

With v6 nearly finalized, our plan is to ship the current milestone first and then introduce dedicated SolidJS support in a subsequent release.

In addition to the feature itself, it would be great to have a dedicated example project featuring the integration, a documentation page (similarly to the existing React Apps Internationalization) and a blog post (optionally). Please let us know your thoughts!

@timofei-iatsenko

Copy link
Copy Markdown
Collaborator

@Huliiiiii we reached v6 milestone. We still interersted in this integration. Could you update the branch to the latest main? (please note, the main branch is renamed from what was next previously, you may need some additional fixes in git). You don't need to keep a git history clean - we will squash all commits into one while merging anyway.

Thanks!

@timofei-iatsenko

Copy link
Copy Markdown
Collaborator

@Huliiiiii i'm going to jump in and help with this PR, so please don't rebase/force push. Thanks!

Comment on lines +205 to +210
["@lingui/react", "@lingui/solid"].some((moduleName) =>
path
.get("openingElement")
.get("name")
.referencesImport(moduleName, "Trans"),
)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Huliiiiii i think we can use macro.runtimeConfigModule.Trans option here and avoid hardcode, could you make it change and at a simple test testing that this property is respected? Thanks!

@timofei-iatsenko

Copy link
Copy Markdown
Collaborator

@Huliiiiii could you please not force push in this branch. We don't care about the history in the feature bunches since they would be squahed and merged any way.

I'm going to push to your branch to help with CI issues.

# Conflicts:
#	yarn.lock
@Huliiiiii

Copy link
Copy Markdown
Author

Sorry, I accidentally force-pushed again.

@Huliiiiii

Copy link
Copy Markdown
Author

I’m unable to reproduce the timeout issue locally. Maybe it’s an issue with the action runner?

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Take a closer look for SolidJS integration

3 participants