Skip to content

Conversation

@sybers
Copy link
Contributor

@sybers sybers commented Feb 7, 2026

This PR adds a script which removes all unused translation keys found by the i18n:report command from all translation files.

It also runs it, and adds a check which fails the CI if there are some unused translations (it used to be a warning only).

@vercel
Copy link

vercel bot commented Feb 7, 2026

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

Project Deployment Actions Updated (UTC)
npmx.dev Ready Ready Preview, Comment Feb 7, 2026 3:55pm
2 Skipped Deployments
Project Deployment Actions Updated (UTC)
docs.npmx.dev Ignored Ignored Preview Feb 7, 2026 3:55pm
npmx-lunaria Ignored Ignored Feb 7, 2026 3:55pm

Request Review

@github-actions
Copy link

github-actions bot commented Feb 7, 2026

Lunaria Status Overview

🌕 This pull request will trigger status changes.

Learn more

By default, every PR changing files present in the Lunaria configuration's files property will be considered and trigger status changes accordingly.

You can change this by adding one of the keywords present in the ignoreKeywords property in your Lunaria configuration file in the PR's title (ignoring all files) or by including a tracker directive in the merged commit's description.

Tracked Files

File Note
lunaria/files/ar-EG.json Localization changed, will be marked as complete.
lunaria/files/az-AZ.json Localization changed, will be marked as complete.
lunaria/files/cs-CZ.json Localization changed, will be marked as complete.
lunaria/files/de-DE.json Localization changed, will be marked as complete.
lunaria/files/en-GB.json Localization changed, will be marked as complete.
lunaria/files/en-US.json Source changed, localizations will be marked as outdated.
lunaria/files/es-419.json Localization changed, will be marked as complete.
lunaria/files/es-ES.json Localization changed, will be marked as complete.
lunaria/files/fr-FR.json Localization changed, will be marked as complete.
lunaria/files/hi-IN.json Localization changed, will be marked as complete.
lunaria/files/hu-HU.json Localization changed, will be marked as complete.
lunaria/files/id-ID.json Localization changed, will be marked as complete.
lunaria/files/it-IT.json Localization changed, will be marked as complete.
lunaria/files/ja-JP.json Localization changed, will be marked as complete.
lunaria/files/mr-IN.json Localization changed, will be marked as complete.
lunaria/files/ne-NP.json Localization changed, will be marked as complete.
lunaria/files/no-NO.json Localization changed, will be marked as complete.
lunaria/files/pl-PL.json Localization changed, will be marked as complete.
lunaria/files/pt-BR.json Localization changed, will be marked as complete.
lunaria/files/ru-RU.json Localization changed, will be marked as complete.
lunaria/files/te-IN.json Localization changed, will be marked as complete.
lunaria/files/uk-UA.json Localization changed, will be marked as complete.
lunaria/files/zh-CN.json Localization changed, will be marked as complete.
lunaria/files/zh-TW.json Localization changed, will be marked as complete.
Warnings reference
Icon Description
🔄️ The source for this localization has been updated since the creation of this pull request, make sure all changes in the source have been applied.

@codecov
Copy link

codecov bot commented Feb 7, 2026

Codecov Report

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

Files with missing lines Patch % Lines
app/components/Filter/Panel.vue 31.57% 13 Missing ⚠️
app/components/Package/Table.vue 84.61% 2 Missing ⚠️
app/components/ColumnPicker.vue 50.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

"search_placeholder_description": "فلترة حسب الوصف…",
"search_placeholder_keywords": "فلترة حسب الكلمات المفتاحية…",
"search_placeholder_all": "فلتر حسب الكل أو استخدم name: desc: kw:",
"scope_name": "الإسم",
Copy link
Contributor

Choose a reason for hiding this comment

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

A quick search reveals this key is actually used (but not in a statically analyzable way) in Panel.vue

Copy link
Member

Choose a reason for hiding this comment

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

hmm. can we fix that?

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 7, 2026

📝 Walkthrough

Walkthrough

Adds i18n command docs to CONTRIBUTING.md; introduces i18n reporting and removal scripts (including a colours utility); updates the translations reporter to fail on missing/unused/dynamic keys; adds a script that prunes unused translation keys from the reference and all locale JSON files; replaces many static i18n key maps with computed useI18n mappings in UI components; and removes a large set of translation keys across many locale and lunaria locale files.

Possibly related PRs

Suggested reviewers

  • danielroe
🚥 Pre-merge checks | ✅ 1
✅ Passed checks (1 passed)
Check name Status Explanation
Description check ✅ Passed The PR description directly relates to the changeset by explaining the addition of a script to remove unused translation keys and a CI check to enforce this.

✏️ 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: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
lunaria/files/es-419.json (1)

473-482: ⚠️ Potential issue | 🟠 Major

Remove all 629 duplicate keys from es-419.json.

This variant file contains translations identical to the base es.json across all sections. Per project guidelines, country variants should only include translations that differ from the base language file. Since the entire file consists of duplicates, either remove all keys and delete the file, or retain only keys with translations differing from es.json (if any exist).

🧹 Nitpick comments (4)
lunaria/files/it-IT.json (1)

730-741: Consider a fuller plural form for ops (if space allows).

"{count} op | {count} op" reads a bit abbreviated in Italian; “operazione | operazioni” would be clearer unless the UI requires a compact label.

i18n/locales/mr-IN.json (3)

175-198: Avoid empty placeholder keys in locale variants.
These empty objects add no translations and can shadow the base Marathi file. For variant locales, keep only keys that differ or provide mr-IN-specific strings.

Proposed cleanup
-    "likes": {},
...
-    "readme": {
-      "callout": {}
-    },
-    "provenance_section": {},

Based on learnings: In the npmx.dev project, when using country locale variants, place only translations that differ from the base language in variant JSON files.


290-300: Remove empty compare placeholders from the variant file.
These entries are empty and should live in the base locale unless mr-IN needs distinct strings.

Proposed cleanup
-    "no_dependency": {},
...
-        "totalLikes": {},

Based on learnings: In the npmx.dev project, when using country locale variants, place only translations that differ from the base language in variant JSON files.


311-324: Keep privacy_policy content in the base locale unless mr-IN differs.
An empty privacy_policy block provides no translation value in a variant file and can mask base keys.

Proposed cleanup
-  "privacy_policy": {
-    "cookies": {
-      "what_are": {},
-      "types": {},
-      "local_storage": {},
-      "management": {}
-    },
-    "analytics": {},
-    "authenticated": {},
-    "data_retention": {},
-    "your_rights": {},
-    "contact": {},
-    "changes": {}
-  }

Based on learnings: In the npmx.dev project, when using country locale variants, place only translations that differ from the base language in variant JSON files.

Comment on lines 739 to 741
"connecting": "连接中…",
"ops": "ops",
"disconnect": "断开连接"
"ops": "ops"
},
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Inspect account_menu.ops across i18n locale files
python - <<'PY'
import json, glob, re
for path in sorted(glob.glob('i18n/locales/*.json')):
    with open(path, encoding='utf-8') as f:
        data = json.load(f)
    val = data.get('account_menu', {}).get('ops')
    if val is not None:
        placeholders = sorted(set(re.findall(r'\{[^}]+\}', val)))
        print(f"{path}: {val}  placeholders={placeholders}")
PY

Repository: npmx-dev/npmx.dev

Length of output: 1556


Translate account_menu.ops and include the {count} placeholder for pluralisation.

The current value "ops" is untranslated English text and lacks the {count} placeholder used across all other locales (e.g., en.json has "{count} op | {count} ops"). Provide a proper Chinese translation with pluralisation support.

Comment on lines +737 to 738
"ops": "操作"
},
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Inspect account_menu.ops across i18n locale files
python - <<'PY'
import json, glob, re
for path in sorted(glob.glob('i18n/locales/*.json')):
    with open(path, encoding='utf-8') as f:
        data = json.load(f)
    val = data.get('account_menu', {}).get('ops')
    if val is not None:
        placeholders = sorted(set(re.findall(r'\{[^}]+\}', val)))
        print(f"{path}: {val}  placeholders={placeholders}")
PY

Repository: npmx-dev/npmx.dev

Length of output: 1556


Add {count} placeholder to zh-TW translation for account_menu.ops.
The base locale (en.json) includes {count} in the value ({count} op | {count} ops), but zh-TW.json provides only the static string "操作" without the placeholder. This will cause incorrect pluralisation handling. Note that zh-CN.json exhibits the same issue.

Comment on lines +740 to 741
"ops": "ops"
},
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Add a proper translation and {count} placeholder for ops.

The current value is the literal English “ops” and drops the count interpolation, so the UI will lose the number.

🔧 Suggested fix
-    "ops": "ops"
+    "ops": "{count} 项操作"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"ops": "ops"
},
"ops": "{count} 项操作"
},

Comment on lines +737 to 738
"ops": "操作"
},
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Inspect account_menu.ops across lunaria locale files
python - <<'PY'
import json, glob, re
for path in sorted(glob.glob('lunaria/files/*.json')):
    with open(path, encoding='utf-8') as f:
        data = json.load(f)
    val = data.get('account_menu', {}).get('ops')
    if val is not None:
        placeholders = sorted(set(re.findall(r'\{[^}]+\}', val)))
        print(f"{path}: {val}  placeholders={placeholders}")
PY

Repository: npmx-dev/npmx.dev

Length of output: 1738


Add {count} placeholder to account_menu.ops translation.
The reference locales include {count} for pluralisation, but the zh-TW translation is missing it. Update from 操作 to include the placeholder (for example, {count} 件操作 following the pattern in ja-JP).

danielroe
danielroe previously approved these changes Feb 7, 2026
@danielroe danielroe dismissed their stale review February 7, 2026 15:07

missed bobbie's point!

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: 3

🧹 Nitpick comments (3)
lunaria/files/te-IN.json (1)

731-731: Consider translating "op/ops" to Telugu for consistency.

The plural form "{count} op | {count} ops" retains the English terms "op" and "ops", whilst the rest of the file translates UI strings to Telugu. If "operations" is intended to remain in English as a technical term, this is acceptable. Otherwise, consider using a Telugu equivalent for consistency with the locale file.

lunaria/files/es-419.json (1)

753-753: Consider localising “op/ops” unless it’s a product term.

If there’s no intentional branding reason to keep English, a Spanish translation avoids UI copy drift.

💬 Suggested localisation
-    "ops": "{count} op | {count} ops"
+    "ops": "{count} operación | {count} operaciones"
app/components/Package/Table.vue (1)

107-109: Consider adding a fallback for consistency with ColumnPicker.vue.

Unlike ColumnPicker.vue (line 61), this getColumnLabel function doesn't have a fallback if the column ID isn't in the mapping. While the current mapping covers all visible columns, adding ?? id would provide defensive safety.

♻️ Optional: add fallback for defensive coding
 function getColumnLabel(id: ColumnId): string {
-  return columnLabels.value[id]
+  return columnLabels.value[id] ?? id
 }

"connecting": "Conectando...",
"ops": "{count} op | {count} ops",
"disconnect": "Desconectar"
"ops": "{count} op | {count} ops"
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Localise the operations count label. "{count} op | {count} ops" is English; consider Spanish wording (e.g., “operación/operaciones”) for consistency with the rest of the locale.

"connecting": "कनेक्ट हो रहा है...",
"ops": "{count} op | {count} ops",
"disconnect": "डिस्कनेक्ट करें"
"ops": "{count} op | {count} ops"
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Localise the operations count label. The ops string is still English; consider a Hindi wording or an accepted abbreviation for consistency.

@sybers sybers force-pushed the cleanup_unused_translation_keys branch from 05ffe11 to 92bb2d9 Compare February 7, 2026 15:52
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: 2

"connecting": "Connexion en cours...",
"ops": "{count} op | {count} ops",
"disconnect": "Déconnexion"
"ops": "{count} op | {count} ops"
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Localise the operations count label.
“op/ops” reads as English; consider a French form (or an abbreviated French form if space is tight).

💬 Suggested tweak
-    "ops": "{count} op | {count} ops"
+    "ops": "{count} opération | {count} opérations"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"ops": "{count} op | {count} ops"
"ops": "{count} opération | {count} opérations"

"connecting": "Connettendo...",
"ops": "{count} op | {count} op",
"disconnect": "Disconnetti"
"ops": "{count} op | {count} op"
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Identical singular and plural forms in pluralisation string.

The pluralisation "{count} op | {count} op" has identical singular and plural forms. If "op" is intentionally an invariable abbreviation for brevity, this is fine. Otherwise, consider using distinct forms like "{count} op | {count} ops" or the full Italian words "{count} operazione | {count} operazioni".

@danielroe danielroe enabled auto-merge February 7, 2026 17:24
@danielroe danielroe added this pull request to the merge queue Feb 7, 2026
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Feb 7, 2026
@danielroe danielroe added this pull request to the merge queue Feb 7, 2026
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Feb 7, 2026
@danielroe danielroe added this pull request to the merge queue Feb 7, 2026
Merged via the queue into npmx-dev:main with commit 7b62459 Feb 7, 2026
17 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