@@ -24,23 +24,60 @@ translations/
2424│ ├── articles.json
2525│ ├── curated-collections.json
2626│ ├── stacks.json
27- │ └── comparison.json
27+ │ ├── comparison.json
28+ │ ├── landscape.json
29+ │ ├── open-source-rank.json
30+ │ └── search.json
2831├── de/ # German
32+ ├── es/ # Spanish
33+ ├── fr/ # French
34+ ├── id/ # Indonesian
35+ ├── ja/ # Japanese
36+ ├── ko/ # Korean
37+ ├── pt/ # Portuguese
38+ ├── ru/ # Russian
39+ ├── tr/ # Turkish
2940├── zh-Hans/ # Simplified Chinese
30- └── ko / # Korean
41+ └── zh-Hant / # Traditional Chinese
3142```
3243
3344** Important:** Each locale must maintain the exact same file structure and JSON key order as ` en/ ` .
3445
46+ ## I18n Architecture
47+
48+ The project has ** two separate internationalization systems** that share the same 12 locale configuration:
49+
50+ ### 1. UI Translation System (next-intl)
51+ - ** Purpose:** Translates static UI strings (buttons, labels, page content, etc.)
52+ - ** Location:** ` translations/{locale}/*.json `
53+ - ** Usage:** Via ` useTranslations() ` hook or ` getTranslations() ` server function
54+ - ** Managed by:** This skill's sync and translate commands
55+
56+ ### 2. Manifest Translation System
57+ - ** Purpose:** Translates manifest data (IDEs, CLIs, models, providers, etc.)
58+ - ** Location:** ` manifests/**/*.json ` (in each manifest file's ` translations ` field)
59+ - ** Usage:** Via ` localizeManifestItem() ` and ` localizeManifestItems() ` functions
60+ - ** Managed by:** Manual editing of manifest files or manifest automation tools
61+
62+ ** This skill manages only the UI Translation System.** For manifest translations, edit the manifest JSON files directly or use the manifest-automation skill.
63+
3564## Enabled Locales
3665
3766Currently enabled locales in ` src/i18n/config.ts ` :
3867- ` en ` - English (source of truth)
3968- ` de ` - Deutsch (German)
40- - ` zh-Hans ` - 简体中文 (Simplified Chinese)
69+ - ` es ` - Español (Spanish)
70+ - ` fr ` - Français (French)
71+ - ` id ` - Bahasa Indonesia (Indonesian)
72+ - ` ja ` - 日本語 (Japanese)
4173- ` ko ` - 한국어 (Korean)
74+ - ` pt ` - Português (Portuguese)
75+ - ` ru ` - Русский (Russian)
76+ - ` tr ` - Türkçe (Turkish)
77+ - ` zh-Hans ` - 简体中文 (Simplified Chinese)
78+ - ` zh-Hant ` - 繁體中文 (Traditional Chinese)
4279
43- Additional locale directories may exist but are not enabled in the config .
80+ All 12 locales are fully enabled and must be maintained in sync .
4481
4582## Subcommands
4683
@@ -117,13 +154,13 @@ Generate translation tasks for Claude Code to translate missing content.
117154When you need to translate content, use this command in Claude Code:
118155
119156```
120- Please run the i18n translate command for zh-Hans
157+ Please run the i18n translate command for ja
121158```
122159
123160Claude Code will execute:
124161
125162``` bash
126- node .claude/skills/i18n/scripts/translate.mjs zh-Hans
163+ node .claude/skills/i18n/scripts/translate.mjs ja
127164```
128165
129166** Workflow:**
@@ -145,13 +182,13 @@ node .claude/skills/i18n/scripts/translate.mjs zh-Hans
145182** Output Example:**
146183
147184```
148- 🌐 Translation Assistant for zh-Hans
185+ 🌐 Translation Assistant for ja
149186
150187━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
151188📝 Translation Task
152189━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
153190
154- Target Language: 简体中文 (Simplified Chinese )
191+ Target Language: 日本語 (Japanese )
155192Entries to translate: 15
156193
157194Files affected:
@@ -168,13 +205,15 @@ Files affected:
168205
169206Content to translate:
170207
208+ ```json
171209{
172210 "components.languageSwitcher.english": "English",
173211 "pages.home.hero.title": "Welcome to AI Coding Stack",
174212 "shared.navigation.docs": "Documentation",
175213 ...
176214}
177215```
216+ ```
178217
179218---
180219
@@ -205,7 +244,16 @@ Each locale has:
205244// translations/en/index.ts
206245import components from './components.json'
207246import articles from './pages/articles.json'
208- // ... other imports
247+ import comparison from './pages/comparison.json'
248+ import curatedCollections from './pages/curated-collections.json'
249+ import docs from './pages/docs.json'
250+ import home from './pages/home.json'
251+ import landscape from './pages/landscape.json'
252+ import manifesto from './pages/manifesto.json'
253+ import openSourceRank from './pages/open-source-rank.json'
254+ import search from './pages/search.json'
255+ import stacks from './pages/stacks.json'
256+ import shared from './shared.json'
209257
210258const messages = {
211259 shared,
@@ -216,8 +264,11 @@ const messages = {
216264 docs,
217265 articles,
218266 curatedCollections,
219- ... stacks ,
267+ stacks,
220268 comparison,
269+ landscape,
270+ openSourceRank,
271+ search,
221272 },
222273}
223274
@@ -244,45 +295,59 @@ Becomes: `pages.home.hero.title = "Welcome"`
244295
245296### Adding a New Language
246297
298+ ** Note:** The project currently supports 12 locales. To add a new locale (e.g., Italian 'it'):
299+
2473001 . Add the locale to ` src/i18n/config.ts ` :
248301
249302``` typescript
250- export const locales = [' en' , ' de' , ' zh-Hans' , ' ko' , ' ja' ] as const ; // Add 'ja'
303+ export const locales = [
304+ ' en' , ' de' , ' es' , ' fr' , ' id' , ' ja' , ' ko' , ' pt' , ' ru' , ' tr' , ' zh-Hans' , ' zh-Hant' ,
305+ ' it' // Add new locale
306+ ] as const ;
251307```
252308
2533092 . Update locale names:
254310
255311``` typescript
256312export const localeNames: Record <Locale , string > = {
257- // ...
258- ja : ' 日本語 ' ,
313+ // ... existing locales
314+ it : ' Italiano ' ,
259315}
260316
261317export const localeToOgLocale: Record <Locale , string > = {
262- // ...
263- ja: ' ja_JP' ,
318+ // ... existing locales
319+ it: ' it_IT' ,
320+ }
321+ ```
322+
323+ 3 . Add to translate.mjs LOCALE_NAMES (` .claude/skills/i18n/scripts/translate.mjs ` ):
324+
325+ ``` javascript
326+ const LOCALE_NAMES = {
327+ // ... existing locales
328+ it: ' Italiano (Italian)' ,
264329}
265330```
266331
267- 3 . Create the locale directory structure:
332+ 4 . Create the locale directory structure:
268333
269334``` bash
270- mkdir -p translations/ja /pages
271- cp translations/en/index.ts translations/ja /index.ts
272- cp translations/en/* .json translations/ja /
273- cp translations/en/pages/* .json translations/ja /pages/
335+ mkdir -p translations/it /pages
336+ cp translations/en/index.ts translations/it /index.ts
337+ cp translations/en/* .json translations/it /
338+ cp translations/en/pages/* .json translations/it /pages/
274339```
275340
276- 4 . Run sync to ensure structure matches:
341+ 5 . Run sync to ensure structure matches:
277342
278343```
279344Please run the i18n sync command
280345```
281346
282- 5 . Run translate to generate translation tasks:
347+ 6 . Run translate to generate translation tasks:
283348
284349```
285- Please run the i18n translate command for ja
350+ Please run the i18n translate command for it
286351```
287352
288353## Best Practices
@@ -329,7 +394,45 @@ const rawMessages = (await import(`../../translations/${locale}/index.ts`)).defa
329394const messages = resolveReferences (rawMessages )
330395```
331396
332- The JSON files are loaded through the index.ts for each locale, and the ` resolveReferences ` function handles ` @:path ` reference syntax.
397+ The JSON files are loaded through the index.ts for each locale, and the ` resolveReferences ` function handles reference syntax.
398+
399+ ### Reference Resolution
400+
401+ The project supports ** reference syntax** for reusing translations:
402+
403+ ** Basic Reference:** ` @:path.to.key `
404+ ``` json
405+ {
406+ "shared" : {
407+ "appName" : " AI Coding Stack" ,
408+ "welcome" : " Welcome to @:shared.appName"
409+ }
410+ }
411+ // Result: "Welcome to AI Coding Stack"
412+ ```
413+
414+ ** Reference with Modifiers:** ` @.modifier:path.to.key `
415+
416+ Supported modifiers:
417+ - ` @.upper:path ` - Convert to UPPERCASE
418+ - ` @.lower:path ` - Convert to lowercase
419+ - ` @.capitalize:path ` - Capitalize first letter
420+
421+ ``` json
422+ {
423+ "terms" : {
424+ "documentation" : " documentation" ,
425+ "title" : " @.capitalize:terms.documentation Guide"
426+ }
427+ }
428+ // Result: "Documentation Guide"
429+ ```
430+
431+ ** Important:**
432+ - References are resolved at runtime by ` src/i18n/lib-core.ts `
433+ - Circular references are detected and will throw an error
434+ - References can be nested (references within references)
435+ - Keep reference syntax intact during translation
333436
334437## License
335438
0 commit comments