Skip to content

feat(require-implicit-id): Add rule to enforce implicit IDs#131

Open
gwolpert wants to merge 5 commits intolingui:mainfrom
gwolpert:gwolpert/require-implicit-id
Open

feat(require-implicit-id): Add rule to enforce implicit IDs#131
gwolpert wants to merge 5 commits intolingui:mainfrom
gwolpert:gwolpert/require-implicit-id

Conversation

@gwolpert
Copy link
Copy Markdown
Contributor

@gwolpert gwolpert commented Apr 15, 2026

require-implicit-id

Enforce that <Trans> components and Lingui macro function calls (t, msg, defineMessage) do not have an explicit id.

Relying on auto-generated IDs eliminates the need to maintain a separate mapping of IDs to messages and ensures the catalog stays in sync with the source code. See Benefits of Generated IDs in the Lingui docs for more details.

⚠️ Conflicts: This rule directly conflicts with require-explicit-id. Do not enable both rules at the same time — they are mutually exclusive.

// nope ⛔️
<Trans id="msg.hello">Hello</Trans>
t({ id: "msg.hello", message: "Hello" })

// ok ✅
<Trans>Hello</Trans>
t({ message: "Hello" })
t`Hello`

…ntext

Add a new rule that disallows explicit id on  and Lingui macros, favoring generated IDs. Supports an optional requireContext setting to mandate a context; tagged templates are reported when context is required.

Register the rule, add docs (including mutual exclusivity with require-explicit-id), extract shared helpers (findJSXAttribute/findObjectProperty), and refactor require-explicit-id to use them. Include comprehensive tests for the new rule.
@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 15, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.19%. Comparing base (05d7ae4) to head (790dcb6).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #131      +/-   ##
==========================================
+ Coverage   98.11%   98.19%   +0.07%     
==========================================
  Files          13       14       +1     
  Lines         636      663      +27     
  Branches      214      211       -3     
==========================================
+ Hits          624      651      +27     
  Misses         12       12              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@gwolpert gwolpert changed the title Add rule to enforce implicit IDs and optionally require context feat(require-implicit-id): Add rule to enforce implicit IDs and optionally require context Apr 15, 2026
@andrii-bodnar
Copy link
Copy Markdown
Contributor

andrii-bodnar commented Apr 15, 2026

Hi @gwolpert, thanks for the contribution!

There is an open PR (#128) that already implements the idea of requiring context for translators. I think it would be better to require the comment parameter instead of context, as it is closer to the idea of providing additional information about the string. The context property plays a slightly different role and is responsible for distinguishing strings with different meanings so that they are not merged in the resulting file.

Please let me know what you think about this.

@gwolpert
Copy link
Copy Markdown
Contributor Author

gwolpert commented Apr 15, 2026

Hi @andrii-bodnar! Thanks for the feedback. I see your point regarding the distinction between context and comments. While context is technical and prevents string merging in the catalogue, comments are purely metadata for the translator.

Documented: https://lingui.dev/guides/explicit-vs-generated-ids

I originally included requireContext as an option because, when using implicit IDs, providing extra metadata becomes even more important for disambiguation. However, we could definitely expand this to support both workflows or even make them interchangeable depending on the team's preference.

In my opinion they serve different purposes in different situations. requireContext is an option I would personally not use, but I wished to offer it to the people who did want it. We could however get rid of the option alltogether and just keep require-implicit-id by itself.

@gwolpert
Copy link
Copy Markdown
Contributor Author

gwolpert commented Apr 15, 2026

On second thought, I think it is actually better to keep context and comment completely separate. Since context and comment serve such different purposes. One being structural for the catalogue and the other being purely informational. Bundling them into the same logic might make the rule less clear.

I will stick to the current implementation of requireContext for this PR. We can then handle the comment requirement as its own distinct rule #128 to keep the plugin's API clean. Let me know if you agree with keeping that separation!

@andrii-bodnar
Copy link
Copy Markdown
Contributor

Thanks for the response! I still think requiring context for every string is unnecessary - context is mainly for disambiguating truly ambiguous messages, not a universal requirement. For general translator guidance, comment is the better fit.

@andrii-bodnar
Copy link
Copy Markdown
Contributor

In addition, this PR is related: lingui/js-lingui#2514. This makes it easier to apply context selectively (e.g. /* @lingui context="checkout" */ in a scoped area), which is useful without making context universal.

@gwolpert
Copy link
Copy Markdown
Contributor Author

@andrii-bodnar Alright, I agree. Do you think it still makes sense to include the functionality to require-implicit-id instead? Or to close the PR alltogether?

I hope you can reuse some of the helpers in your other PR.

@gwolpert gwolpert changed the title feat(require-implicit-id): Add rule to enforce implicit IDs and optionally require context feat(require-implicit-id): Add rule to enforce implicit IDs Apr 15, 2026
@gwolpert
Copy link
Copy Markdown
Contributor Author

gwolpert commented Apr 15, 2026

I have simplified the PR to focus strictly on enforcing implicit IDs. The rule now specifically forbids the use of the explicit id property to ensure the project remains consistent with one of the two recommended Lingui's workflows and prevent any hybrid solutions.

@andrii-bodnar
Copy link
Copy Markdown
Contributor

@gwolpert thank you! I think this new rule is a good and natural addition to the require-explicit-id rule. With these two rules, we have coverage for both Lingui usage approaches.

I noticed that you primarily focus on the Trans component, but the Plural, SelectOrdinal and Select components also accept id. It would be great to cover these as well. What do you think?

Extend both require-explicit-id and require-implicit-id to cover Lingui ICU JSX components (, , ). Add shared query helper, enforce/forbid id consistently, and validate patterns for explicit IDs. Update docs and tests to reflect the new coverage.
@gwolpert
Copy link
Copy Markdown
Contributor Author

Updated to add the ICU components to the require-explicit and require-implicit rules

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 a new ESLint rule to enforce Lingui “generated IDs” usage (no explicit id), and expands the existing explicit-id rule to cover Lingui ICU components as well.

Changes:

  • Introduce require-implicit-id rule (implementation, tests, docs) and register it in the plugin.
  • Add shared AST helpers (findJSXAttribute, findObjectProperty) plus an ICU component selector (LinguiIcuComponentQuery).
  • Extend require-explicit-id to validate ICU components and refactor to use the new helpers; update tests/docs accordingly.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
tests/src/rules/require-implicit-id.test.ts New RuleTester coverage for the implicit-id rule across <Trans>, ICU components, and macro calls.
tests/src/rules/require-explicit-id.test.ts Adds coverage for ICU components and a couple of documented “skip” cases for non-string/boolean ids.
src/rules/require-implicit-id.ts New rule forbidding explicit id on <Trans>, ICU components, and macro call objects.
src/rules/require-explicit-id.ts Refactors JSX/object-property detection via helpers and adds ICU component enforcement.
src/index.ts Registers the new rule in the exported plugin rules map.
src/helpers.ts Adds ICU selector and helper utilities for finding JSX attributes and object properties.
src/helpers.test.ts Adds unit tests for the new helper utilities.
docs/rules/require-implicit-id.md New documentation page for the rule.
docs/rules/require-explicit-id.md Updates docs to mention ICU components + notes mutual exclusivity with implicit-id rule.
README.md Adds the new rule to the documentation list.

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

Comment thread src/rules/require-implicit-id.ts Outdated
Comment thread src/rules/require-implicit-id.ts Outdated
Comment thread src/rules/require-explicit-id.ts
Comment thread src/rules/require-implicit-id.ts
Also refactor require-implicit-id to reuse found id attribute/property when reporting, avoiding duplicate lookups.
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