Skip to content

feat: add optional configurable JSX placeholder naming#207

Merged
andrii-bodnar merged 9 commits into
lingui:nextfrom
mogelbrod:jsx-placeholder-naming
Apr 17, 2026
Merged

feat: add optional configurable JSX placeholder naming#207
andrii-bodnar merged 9 commits into
lingui:nextfrom
mogelbrod:jsx-placeholder-naming

Conversation

@mogelbrod
Copy link
Copy Markdown
Contributor

@mogelbrod mogelbrod commented Apr 9, 2026

Description

SWC implementation of lingui/js-lingui#2505

Add a new feature that allows developers to customize the identifiers of JSX placeholders generated by the <Trans> macro. This results in placeholder identifiers in extracted messages that are more stable, human-readable, and contextual, instead of the default arbitrary numeric indices (e.g., replacing <0> with <em> or <link>).

It is accomplished via two new optional configuration options (via lingui.config.js in the macro options):

  1. jsxPlaceholderAttribute: Allows defining a custom prop name (e.g., _t) that can be used on components to set an explicit placeholder name locally.
  2. jsxPlaceholderDefaults: Allows providing a record of tag names to placeholder names, enabling global default renaming for specific JSX components.

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

Fixes #1188

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) - will do before merging

Disclaimer

Much of this PR was generated by Copilot using the Gemini 3.1 Pro (Preview) model with training/sharing disabled.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds optional configuration for more stable, human-readable JSX placeholder identifiers generated from <Trans> JSX, aligning the SWC plugin behavior with LinguiJS’ macro feature request.

Changes:

  • Introduces jsxPlaceholderAttribute and jsxPlaceholderDefaults options and threads them into message building.
  • Updates MessageBuilder to emit named JSX placeholders (with suffixing for collisions) and strip the naming attribute from generated component AST.
  • Adds JSX fixture tests and snapshot outputs covering named placeholders, defaults, deduplication, and prop-order scenarios.

Reviewed changes

Copilot reviewed 14 out of 15 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
yarn.lock Regenerated lockfile (currently switched to Yarn v1 format).
tests/jsx.rs Adds new test cases for named JSX placeholders and dedup/suffix behavior.
tests/swc_snapshots/tests/jsx.rs/jsx_named_placeholders_basic.js Snapshot for _t-driven placeholder naming.
tests/swc_snapshots/tests/jsx.rs/jsx_named_placeholders_stripped_ast.js Snapshot verifying _t attribute stripping from emitted component AST.
tests/swc_snapshots/tests/jsx.rs/jsx_named_placeholders_defaults.js Snapshot for global defaults-based placeholder naming.
tests/swc_snapshots/tests/jsx.rs/jsx_named_placeholders_deduplication_different_props.js Snapshot for suffixing when same placeholder name has different props.
tests/swc_snapshots/tests/jsx.rs/jsx_named_placeholders_deduplication_identical.js Snapshot for deduplication when same placeholder name + identical props repeats.
tests/swc_snapshots/tests/jsx.rs/jsx_named_placeholders_deduplication_with_stripped_props.js Snapshot for deduplication when _t is stripped and props determine equality.
tests/swc_snapshots/tests/jsx.rs/jsx_named_placeholders_attribute_ignored_when_not_configured.js Snapshot ensuring _t is ignored unless configured.
tests/swc_snapshots/tests/jsx.rs/jsx_named_placeholders_prop_order.js Snapshot for behavior when same props appear in different orders.
tests/swc_snapshots/tests/jsx.rs/jsx_named_placeholders_prop_order2.js Snapshot for behavior when props differ.
src/options.rs Adds new options to config struct, normalization, and defaults.
src/lib.rs Passes options into MessageBuilder::parse and simplifies replacer handling.
src/js_macro_folder.rs Passes options into MessageBuilder::parse for JS macro paths.
src/builder.rs Implements placeholder naming logic, dedup/suffixing, and _t attr stripping.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/builder.rs Outdated
Comment thread src/builder.rs
Comment thread src/options.rs
@mogelbrod
Copy link
Copy Markdown
Contributor Author

Note that this PR hasn't been updated to align with the changes in lingui/js-lingui#2505 - will do so once the final API has been decided.

@andrii-bodnar
Copy link
Copy Markdown
Contributor

andrii-bodnar commented Apr 17, 2026

@mogelbrod could you please align this PR with the final Babel version? Thanks!

@mogelbrod
Copy link
Copy Markdown
Contributor Author

@andrii-bodnar I've pushed a commit that aligns this SWC implementation with lingui/js-lingui#2505

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 20 out of 21 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/builder.rs
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 20 out of 21 changed files in this pull request and generated 1 comment.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread src/builder.rs
@andrii-bodnar
Copy link
Copy Markdown
Contributor

@mogelbrod thank you! Please also check failing CI/CD pipelines

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 17, 2026

Codecov Report

❌ Patch coverage is 96.27329% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 92.83%. Comparing base (5f673bd) to head (219a9c0).
⚠️ Report is 1 commits behind head on next.

Files with missing lines Patch % Lines
src/builder.rs 95.38% 6 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             next     #207      +/-   ##
==========================================
+ Coverage   92.59%   92.83%   +0.24%     
==========================================
  Files           8        8              
  Lines        1444     1578     +134     
==========================================
+ Hits         1337     1465     +128     
- Misses        107      113       +6     
Flag Coverage Δ
unittests 92.83% <96.27%> (+0.24%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
src/js_macro_folder.rs 97.70% <100.00%> (ø)
src/lib.rs 91.72% <100.00%> (-0.05%) ⬇️
src/options.rs 100.00% <100.00%> (ø)
src/builder.rs 97.26% <95.38%> (-1.65%) ⬇️
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@andrii-bodnar
Copy link
Copy Markdown
Contributor

@mogelbrod It looks like the yarn.lock file was unnecessarily modified in this PR, causing the "E2E Smoke Test" to fail

@mogelbrod
Copy link
Copy Markdown
Contributor Author

@mogelbrod It looks like the yarn.lock file was unnecessarily modified in this PR, causing the "E2E Smoke Test" to fail

Thanks! I've checked out the version from next. mise wasn't picking up the yarn version from package.json - after installing the correct yarn version I get the correct yarn.lock output.

@andrii-bodnar andrii-bodnar merged commit f4b674d into lingui:next Apr 17, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants