Skip to content

feat(i18n): detect missing and dynamic translation keys#1046

Merged
danielroe merged 3 commits intonpmx-dev:mainfrom
sybers:feat/detect-missing-and-unused-i18n-keys
Feb 6, 2026
Merged

feat(i18n): detect missing and dynamic translation keys#1046
danielroe merged 3 commits intonpmx-dev:mainfrom
sybers:feat/detect-missing-and-unused-i18n-keys

Conversation

@sybers
Copy link
Contributor

@sybers sybers commented Feb 5, 2026

Add i18n validation to CI

What's this about?

Added a script that checks if all translation keys used in the code actually exist in our locale files. It also flags dynamic keys like $t(someVariable) which can't be statically validated.

Changes

  • New script scripts/find-invalid-translations.ts powered by vue-i18n-extract
  • New CI job that runs on every PR
  • Fixed a few components that had hardcoded strings or weird key patterns

Why bother?

Right now, if someone uses $t('typo.in.key'), nothing breaks during build, it just shows up broken for users.

This catches those issues before they get merged. The CI will fail on:

  • Missing keys (typos, forgotten translations)
  • Dynamic keys (impossible to validate statically)
  • Unused keys are just warnings, no need to block PRs for cleanup tasks.

Long term

As we add more locales, manually checking translations becomes impossible. Better to automate it now than debug weird blank strings in production later 😄

@vercel
Copy link

vercel bot commented Feb 5, 2026

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

Project Deployment Actions Updated (UTC)
docs.npmx.dev Error Error Feb 6, 2026 10:30am
npmx.dev Ready Ready Preview, Comment Feb 6, 2026 10:30am
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
npmx-lunaria Ignored Ignored Feb 6, 2026 10:30am

Request Review

@codecov
Copy link

codecov bot commented Feb 5, 2026

Codecov Report

❌ Patch coverage is 71.87500% with 9 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
app/components/ColumnPicker.vue 25.00% 2 Missing and 1 partial ⚠️
app/components/Package/VulnerabilityTree.vue 25.00% 3 Missing ⚠️
app/components/Org/MembersPanel.vue 77.77% 2 Missing ⚠️
app/components/Package/Replacement.vue 88.88% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 5, 2026

📝 Walkthrough

Walkthrough

Adds i18n validation tooling and centralises translation label resolution across multiple Vue components. Introduces a CI job "🌐 i18n validation" running on ubuntu-24.04-arm that checks out the repo, sets up Node (latest LTS), installs pnpm, installs root dependencies without running scripts, and runs pnpm i18n:report. Adds vue-i18n-extract, a new i18n:report script, and a CLI scripts/find-invalid-translations.ts that reports missing, dynamic and unused keys and fails on missing/dynamic keys. Refactors several components to use local translation maps and helper getters instead of inline t(...) calls.

Possibly related PRs

Suggested reviewers

  • userquin
🚥 Pre-merge checks | ✅ 1
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The pull request description clearly relates to the changeset, providing context about i18n validation, the new script, CI job, and component fixes.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

🧹 Nitpick comments (1)
app/components/Org/MembersPanel.vue (1)

358-359: Minor inconsistency with role label approach.

The role filter buttons use getRoleLabel(), but the role <select> options at lines 476-478 use direct $t() calls. Both approaches work, but consider using getRoleLabel() consistently if the goal is to centralise role label management.

Copy link
Member

@danielroe danielroe left a comment

Choose a reason for hiding this comment

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

🚀

@danielroe
Copy link
Member

I also think we might consider auto-pruning unused keys 🙏

@danielroe danielroe added this pull request to the merge queue Feb 6, 2026
Merged via the queue into npmx-dev:main with commit 88be800 Feb 6, 2026
17 of 18 checks passed
@sybers
Copy link
Contributor Author

sybers commented Feb 6, 2026

I also think we might consider auto-pruning unused keys 🙏

Good idea, will open a PR for this as well :)

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.

2 participants