Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .changeset/eloqnt-lint-i18n-cleanup.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@node-core/website-i18n': patch
---

Remove unused and superfluous message keys from all locales, and restore
dropped ICU arguments in the Spanish EOL warning and the Traditional Chinese
package-manager notice, as reported by `eloqnt lint`.
43 changes: 43 additions & 0 deletions .eloqnt/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { defineConfig } from '@eloqnt/cli';

import localeConfig from '../packages/i18n/src/config.json' with { type: 'json' };

export default defineConfig({
srcPath: ['./apps/site'],
messages: {
path: './packages/i18n/src/locales',
locales: localeConfig
.filter(locale => locale.enabled)
.map(locale => locale.code),
sourceLocale: 'en',
format: 'json',
},

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Since this consumes files both from ./apps/site and ./packages/i18n, I've added this as a monorepo dependency.

lint: {
overrides: [
{
// These keys are built at runtime, so static analysis cannot
// see which ones are in use.
keys: [
'components.containers.footer.links.*',
'components.containers.navBar.links.*',
'components.navigation.about.links.*',
'components.navigation.getInvolved.links.*',
'layouts.download.codeBox.platformInfo.*',
'layouts.blog.categories.*',
'components.eolChip.severity.*',

// These namespaces also hold statically referenced keys, so the
// dynamic ones are listed individually.
'components.metabar.author',
'components.metabar.authors',
'components.releaseModal.title',
'components.releaseModal.titleWithoutCodename',
'components.banner.default',
'components.banner.warning',
'components.banner.error',
],
rules: { 'orphan-message': 'off' },
},
],

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

A few exceptions to avoid refactors to code (see also: orphan-messages false positives)

},
});
2 changes: 1 addition & 1 deletion .github/workflows/lint-and-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ jobs:
if: |
(github.event_name == 'push' || github.event_name == 'merge_group') ||
(github.event_name == 'pull_request' && github.event.pull_request.head.ref != 'chore/crowdin')
run: node_modules/.bin/turbo lint lint:types prettier --cache-dir=.turbo/cache
run: node_modules/.bin/turbo lint lint:types prettier //#lint:i18n --cache-dir=.turbo/cache

- name: Save Lint Cache
# We only want to save caches on `push` events or `pull_request_target` events
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"format": "turbo //#prettier:fix prettier:fix lint:fix",
"lint": "turbo lint",
"lint:fix": "turbo lint:fix",
"lint:i18n": "eloqnt lint",
"lint:staged": "lint-staged",
"lint:types": "turbo lint:types",
"prepare": "husky",
Expand All @@ -42,6 +43,7 @@
"devDependencies": {
"@changesets/changelog-github": "^0.7.0",
"@changesets/cli": "^2.31.1",
"@eloqnt/cli": "^0.6.9",
"@eslint/js": "~10.0.1",
"@reporters/github": "^2.0.2",
"@testing-library/react": "~16.3.2",
Expand Down
46 changes: 2 additions & 44 deletions packages/i18n/src/locales/ar.json

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Rule: orphan-message

Dead-key removal (this file and every other locale file). 36 keys are deleted because they are referenced nowhere in the repository — verified with a repo-wide literal search excluding the locale catalogs, plus a hand-check of the dynamic call sites that could theoretically reach them. The same 36 keys are removed from en.json and all locale files, including this disabled ar.json so it doesn't drift further; the per-locale hunks are this one change mirrored, not separate decisions. The non-obvious cases are called out on their lines below.


Generated by Claude Code

Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,7 @@
"about": "حول",
"download": "تنزيل",
"docs": "التوثيق",
"guides": "الأدلة",
"learn": "تعلّم",
"security": "الأمان",
Comment on lines -39 to -41

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Rule: orphan-message

guides and security look load-bearing but aren't: navbar labels are consumed via t(link.text) with keys stored in apps/site/navigation.json, and that file has no entry pointing at either — every other navBar.links.* key has one.


Generated by Claude Code

"certification": "الدورات",
"blog": "المدونة",
"contribute": "المساهمة"
Expand Down Expand Up @@ -70,9 +68,7 @@
},
"downloadReleasesTable": {
"version": "Node.js",
"nApiVersion": "N-API",
"codename": "الاسم الرمزي",
"releaseDate": "تاريخ الإصدار",
"firstReleased": "أول إصدار",
"lastUpdated": "آخر تحديث",
"status": "الحالة",
Expand All @@ -86,10 +82,7 @@
"releaseModal": {
"title": "Node.js v{version} ({codename})",
"titleWithoutCodename": "Node.js v{version}",
"overview": "نظرة عامة",
"minorVersions": "الإصدارات الفرعية",
"releaseAnnouncement": "إعلان الإصدار",
"unsupportedVersionWarning": "هذا الإصدار خارج مرحلة الصيانة. يرجى استخدام إصدار مدعوم. <link>تعرّف على دعم EOL.</link>",
Comment on lines -89 to -92

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Rule: orphan-message

The release modal only renders title, titleWithoutCodename, minorVersions and ltsVersionFeaturesNotice; overview, releaseAnnouncement and unsupportedVersionWarning have no call site.

Deleting unsupportedVersionWarning here also resolves an inconsistent-args error on this key in zh-tw (that translation had dropped the <link> tag) without spending a translation on a dead key — the live EOL warning is the separate layouts.download.codeBox.unsupportedVersionWarning.


Generated by Claude Code

"ltsVersionFeaturesNotice": "هل تريد الميزات الجديدة في وقت أقرب؟ استخدم <link>أحدث إصدار من Node.js</link> بدلًا من ذلك وجرب أحدث التحسينات!"
},
"eolAlert": {
Expand Down Expand Up @@ -121,7 +114,6 @@
"eolTable": {
"version": "الإصدار",
"codename": "الاسم الرمزي",
"releaseDate": "تاريخ الإصدار",
"lastUpdated": "آخر تحديث",
"vulnerabilities": "الثغرات",
"details": "التفاصيل",
Expand All @@ -134,7 +126,6 @@
"npmVersion": "إصدار npm",
"v8Version": "إصدار V8",
"actions": {
"release": "الإصدار",
"changelog": "سجل التغييرات",
"docs": "التوثيق"
}
Expand All @@ -150,8 +141,7 @@
"common": {
"alertBox": {
"info": "معلومة",
"warning": "تحذير",
"danger": "خطر"
"warning": "تحذير"
},
"breadcrumbs": {
"navigateToHome": "الانتقال إلى الصفحة الرئيسية"
Expand Down Expand Up @@ -179,12 +169,10 @@
"metabar": {
"lastUpdated": "آخر تحديث",
"readingTime": "مدة القراءة",
"addedIn": "أضيف في",
"author": "المؤلف",
"authors": "المؤلفون",
"contribute": "المساهمة",
"contributeText": "عدّل هذه الصفحة",
"viewAs": "عرض كـ",
Comment on lines -182 to -187

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Rule: orphan-message

addedIn and viewAs sit under a namespace a dynamic call site reaches, so they deserve a closer look: the template in withMetaBar.tsx is t(`components.metabar.${usernames.length > 1 ? 'authors' : 'author'}`) and can only ever produce .author or .authors. The only occurrences of these two keys are mock props in MetaBar/index.stories.tsx — Storybook fixture data, not a render path.


Generated by Claude Code

"tableOfContents": "جدول المحتويات",
"metadata": "بيانات المقال"
},
Expand All @@ -196,25 +184,7 @@
},
"search": {
"searchPlaceholder": "ابدأ الكتابة...",
"chatPlaceholder": "اسألني عن أي شيء",
"noResultsFoundFor": "لم يتم العثور على نتائج لـ",
"suggestions": "اقتراحات",
"seeAll": "عرض الكل",
"addMore": "إضافة المزيد",
"clearChat": "مسح المحادثة",
"errorMessage": "حدث خطأ أثناء محاولة البحث. يرجى المحاولة مرة أخرى.",
"disclaimer": "قد تخطئ ملخصات AI. يرجى التحقق من المعلومات.",
"startYourSearch": "ابدأ البحث",
"initErrorSearch": "تعذّر تهيئة خدمة البحث",
"initErrorChat": "تعذّر تهيئة خدمة الدردشة",
"chatButtonLabel": "الحصول على ملخص AI",
"searchButtonLabel": "بحث",
"poweredBy": "مدعوم من",
"suggestionOne": "كيف أثبّت Node.js؟",
"suggestionTwo": "كيف أنشئ خادم HTTP؟",
"suggestionThree": "ترقية إصدار Node.js",
"scrollToBottom": "التمرير إلى الأسفل",
"closeChat": "إغلاق الدردشة",
Comment on lines -199 to -217

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Rule: orphan-message

These 18 components.search.* keys are leftovers from the removed search-chat feature. withSearch.tsx uses only the search keys that remain (searchPlaceholder, noResultsFoundFor, keyboardShortcuts.*). In es and tr, seeAll and poweredBy had additionally drifted into objects with a .text child, which is why their deletion also clears four superfluous-key errors.


Generated by Claude Code

"keyboardShortcuts": {
"select": "للاختيار",
"navigate": "للتنقل",
Expand All @@ -229,14 +199,6 @@
}
},
"layouts": {
"blogPost": {
"author": {
"byLine": "{author, select, null {} other {بواسطة {author}، }}"
}
},
"blogIndex": {
"categoryName": "{category, select, all {المدونة} other {منشورات مدونة {category}}}"
},
"blog": {
"title": "المدونة",
"selectCategory": "التصنيفات",
Expand All @@ -245,7 +207,6 @@
"announcements": "الإعلانات",
"release": "الإصدارات",
"vulnerability": "الثغرات",
"advisory-board": "المجلس الاستشاري",

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Rule: orphan-message

layouts.blog.categories.advisory-board: the BlogCategory type derives from this namespace, so every key here is a valid category by construction — but reachability is decided by content. No blog post in apps/site/pages/*/blog carries category: advisory-board in its front matter; the 13 categories in use plus the all tab are exactly the keys that remain.


Generated by Claude Code

"community": "المجتمع",
"feature": "ميزة",
"module": "الوحدات",
Expand Down Expand Up @@ -278,7 +239,6 @@
"platform": "المنصة",
"os": "نظام التشغيل",
"version": "الإصدار",
"installMethod": "طريقة التثبيت",
"packageManager": "مدير الحزم",
"unknown": "غير معروف",
"platformGroups": {
Expand All @@ -288,7 +248,6 @@
},
"codeBox": {
"unsupportedVersionWarning": "هذا الإصدار خارج مرحلة الصيانة. يرجى استخدام إصدار مدعوم حاليًا. <link>تعرّف على دعم EOL.</link>",
"ltsVersionFeaturesNotice": "هل تريد الميزات الجديدة في وقت أقرب؟ استخدم <link>أحدث إصدار من Node.js</link> بدلًا من ذلك وجرب أحدث التحسينات!",
"communityPlatformInfo": "طرق التثبيت التي تعتمد على برمجيات المجتمع تدعمها الفرق المسؤولة عن صيانة تلك البرمجيات.",
"externalSupportInfo": "إذا واجهت أي مشاكل، يرجى زيارة <link>موقع {platform}</link>",
"noScriptDetected": "تتطلب هذه الصفحة JavaScript. يمكنك تنزيل Node.js بدون JavaScript عبر زيارة <link>صفحة أرشيف التنزيلات</link> مباشرة.",
Expand All @@ -300,8 +259,7 @@
"choco": "Chocolatey هو مدير حزم لـ Windows.",
"docker": "Docker هو منصة للحاويات.",
"n": "\"n\" هو مدير إصدارات Node.js متعدد المنصات.",
"asdf": "\"asdf\" هو مدير إصدارات يعمل على عدة أنظمة تشغيل ويدعم عدة لغات برمجية.",
"volta": "\"Volta\" هو مدير إصدارات Node.js متعدد المنصات."
"asdf": "\"asdf\" هو مدير إصدارات يعمل على عدة أنظمة تشغيل ويدعم عدة لغات برمجية."
}
}
},
Expand Down
46 changes: 2 additions & 44 deletions packages/i18n/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,7 @@
"download": "Download",
"docs": "Docs",
"betaDocs": "Beta Docs",
"guides": "Guides",
"learn": "Learn",
"security": "Security",
"certification": "Courses",
"blog": "Blog",
"contribute": "Contribute"
Expand Down Expand Up @@ -71,9 +69,7 @@
},
"downloadReleasesTable": {
"version": "Node.js",
"nApiVersion": "N-API",
"codename": "Codename",
"releaseDate": "Released at",
"firstReleased": "First released",
"lastUpdated": "Last updated",
"status": "Status",
Expand All @@ -87,10 +83,7 @@
"releaseModal": {
"title": "Node.js v{version} ({codename})",
"titleWithoutCodename": "Node.js v{version}",
"overview": "Overview",
"minorVersions": "Minor versions",
"releaseAnnouncement": "Release Announcement",
"unsupportedVersionWarning": "This version is out of maintenance. Please use a supported version. <link>Understand EOL support.</link>",
"ltsVersionFeaturesNotice": "Want new features sooner? Get the <link>latest Node.js version</link> instead and try the latest improvements!"
},
"eolAlert": {
Expand Down Expand Up @@ -122,7 +115,6 @@
"eolTable": {
"version": "Version",
"codename": "Codename",
"releaseDate": "Released at",
"lastUpdated": "Last updated",
"vulnerabilities": "Vulnerabilities",
"details": "Details",
Expand All @@ -135,7 +127,6 @@
"npmVersion": "npm version",
"v8Version": "V8 version",
"actions": {
"release": "Release",
"changelog": "Changelog",
"docs": "Docs"
}
Expand All @@ -151,8 +142,7 @@
"common": {
"alertBox": {
"info": "Info",
"warning": "Warning",
"danger": "Danger"
"warning": "Warning"
},
"breadcrumbs": {
"navigateToHome": "Navigate to Home"
Expand Down Expand Up @@ -180,12 +170,10 @@
"metabar": {
"lastUpdated": "Last Updated",
"readingTime": "Reading Time",
"addedIn": "Added In",
"author": "Author",
"authors": "Authors",
"contribute": "Contribute",
"contributeText": "Edit this page",
"viewAs": "View as",
"tableOfContents": "Table of Contents",
"metadata": "Article metadata"
},
Expand All @@ -197,25 +185,7 @@
},
"search": {
"searchPlaceholder": "Start typing...",
"chatPlaceholder": "Ask me anything",
"noResultsFoundFor": "No results found for",
"suggestions": "Suggestions",
"seeAll": "See all",
"addMore": "Add more",
"clearChat": "Clear chat",
"errorMessage": "An error occurred while trying to search. Please try again.",
"disclaimer": "AI summaries can make mistakes. Please verify the information.",
"startYourSearch": "Start your search",
"initErrorSearch": "Unable to initialize search service",
"initErrorChat": "Unable to initialize chat service",
"chatButtonLabel": "Get an AI summary",
"searchButtonLabel": "Search",
"poweredBy": "Powered by",
"suggestionOne": "How to install Node.js?",
"suggestionTwo": "How to create an HTTP server?",
"suggestionThree": "Upgrading Node.js version",
"scrollToBottom": "Scroll to bottom",
"closeChat": "Close chat",
"keyboardShortcuts": {
"select": "to select",
"navigate": "to navigate",
Expand All @@ -230,14 +200,6 @@
}
},
"layouts": {
"blogPost": {
"author": {
"byLine": "{author, select, null {} other {By {author}, }}"
}
},
"blogIndex": {
"categoryName": "{category, select, all {Blog} other {{category} Blog Posts}}"
},
"blog": {
"title": "Blog",
"selectCategory": "Categories",
Expand All @@ -246,7 +208,6 @@
"announcements": "Announcements",
"release": "Releases",
"vulnerability": "Vulnerabilities",
"advisory-board": "Advisory Board",
"community": "Community",
"feature": "Feature",
"module": "Module",
Expand Down Expand Up @@ -279,7 +240,6 @@
"platform": "Platform",
"os": "Operating System",
"version": "Version",
"installMethod": "Install Method",
"packageManager": "Package Manager",
"unknown": "Unknown",
"platformGroups": {
Expand All @@ -289,7 +249,6 @@
},
"codeBox": {
"unsupportedVersionWarning": "This version is out of maintenance. Please use a currently supported version. <link>Understand EOL support.</link>",
"ltsVersionFeaturesNotice": "Want new features sooner? Get the <link>latest Node.js version</link> instead and try the latest improvements!",
"communityPlatformInfo": "Installation methods that involve community software are supported by the teams maintaining that software.",
"externalSupportInfo": "If you encounter any issues please visit <link>{platform}'s website</link>",
"noScriptDetected": "This page requires JavaScript. You can download Node.js without JavaScript by visiting the <link>downloads archive page</link> directly.",
Expand All @@ -301,8 +260,7 @@
"choco": "Chocolatey is a package manager for Windows.",
"docker": "Docker is a containerization platform.",
"n": "\"n\" is a cross-platform Node.js version manager.",
"asdf": "\"asdf\" is a cross-platform version manager that supports multiple languages.",
"volta": "\"Volta\" is a cross-platform Node.js version manager."
"asdf": "\"asdf\" is a cross-platform version manager that supports multiple languages."
}
}
},
Expand Down
Loading
Loading