|
| 1 | +--- |
| 2 | +name: i18n |
| 3 | +description: Internationalization management tool for syncing and translating language files |
| 4 | +--- |
| 5 | + |
| 6 | +# I18n Management Skill |
| 7 | + |
| 8 | +Manage multilingual content in the `messages/` directory. This skill provides tools to synchronize language files with the English reference and assist with translations. |
| 9 | + |
| 10 | +## Overview |
| 11 | + |
| 12 | +This project uses `next-intl` for internationalization with JSON message files stored in `messages/`: |
| 13 | + |
| 14 | +- `messages/en.json` - English (source of truth) |
| 15 | +- `messages/zh-Hans.json` - Simplified Chinese |
| 16 | +- Additional language files can be added |
| 17 | + |
| 18 | +All language files must maintain the same nested key structure as `en.json`. |
| 19 | + |
| 20 | +## Subcommands |
| 21 | + |
| 22 | +### `sync` |
| 23 | + |
| 24 | +Synchronize all language files with `en.json` as the source of truth. |
| 25 | + |
| 26 | +**What it does:** |
| 27 | + |
| 28 | +- Scans all `.json` files in `messages/` directory |
| 29 | +- Compares each file's keys with `en.json` |
| 30 | +- **Adds missing keys** with English text as placeholder (needs translation) |
| 31 | +- **Removes extra keys** not present in `en.json` |
| 32 | +- Preserves JSON structure and formatting (2-space indentation) |
| 33 | + |
| 34 | +**Usage:** |
| 35 | + |
| 36 | +When you need to sync language files, use this command in Claude Code: |
| 37 | + |
| 38 | +``` |
| 39 | +Please run the i18n sync command |
| 40 | +``` |
| 41 | + |
| 42 | +Claude Code will execute: |
| 43 | + |
| 44 | +```bash |
| 45 | +node .claude/skills/i18n/scripts/sync.mjs |
| 46 | +``` |
| 47 | + |
| 48 | +**Output Example:** |
| 49 | + |
| 50 | +``` |
| 51 | +🔄 Syncing language files with en.json... |
| 52 | +
|
| 53 | +✓ Synced zh-Hans.json |
| 54 | + + Added 3 keys |
| 55 | + - Removed 1 key |
| 56 | +
|
| 57 | +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ |
| 58 | +✓ Sync complete! |
| 59 | + Modified: 1 file |
| 60 | + Added: 3 keys |
| 61 | + Removed: 1 key |
| 62 | +``` |
| 63 | + |
| 64 | +**When to use:** |
| 65 | + |
| 66 | +- After adding new keys to `en.json` |
| 67 | +- After removing obsolete keys from `en.json` |
| 68 | +- Before starting translation work (ensures all keys exist) |
| 69 | +- When adding a new language file |
| 70 | + |
| 71 | +--- |
| 72 | + |
| 73 | +### `translate <locale>` |
| 74 | + |
| 75 | +Generate translation tasks for Claude Code to translate missing content. |
| 76 | + |
| 77 | +**What it does:** |
| 78 | + |
| 79 | +- Reads `en.json` and `<locale>.json` |
| 80 | +- Identifies keys that need translation (currently in English or missing) |
| 81 | +- Outputs a structured translation task with guidelines |
| 82 | +- Provides context and instructions for accurate translation |
| 83 | + |
| 84 | +**Usage:** |
| 85 | + |
| 86 | +When you need to translate content, use this command in Claude Code: |
| 87 | + |
| 88 | +``` |
| 89 | +Please run the i18n translate command for zh-Hans |
| 90 | +``` |
| 91 | + |
| 92 | +Claude Code will execute: |
| 93 | + |
| 94 | +```bash |
| 95 | +node .claude/skills/i18n/scripts/translate.mjs zh-Hans |
| 96 | +``` |
| 97 | + |
| 98 | +**Workflow:** |
| 99 | + |
| 100 | +1. The script outputs content that needs translation in JSON format |
| 101 | +2. Claude Code reads the guidelines and translates the content |
| 102 | +3. You provide the translated JSON back |
| 103 | +4. Claude Code updates the language file |
| 104 | + |
| 105 | +**Translation Guidelines (automatically enforced):** |
| 106 | + |
| 107 | +✓ **Preserve brand names:** `AI Coding Stack`, `Claude Code`, etc. |
| 108 | +✓ **Keep placeholders intact:** `{count}`, `{name}`, `${variable}` |
| 109 | +✓ **Don't translate URLs:** `https://example.com` |
| 110 | +✓ **Don't translate file paths:** `/path/to/file` |
| 111 | +✓ **Maintain terminology consistency** throughout the translation |
| 112 | + |
| 113 | +**Supported Locales:** |
| 114 | + |
| 115 | +- `zh-Hans` - 简体中文 (Simplified Chinese) |
| 116 | +- `zh-Hant` - 繁體中文 (Traditional Chinese) |
| 117 | +- `ja` - 日本語 (Japanese) |
| 118 | +- `ko` - 한국어 (Korean) |
| 119 | +- `fr` - Français (French) |
| 120 | +- `de` - Deutsch (German) |
| 121 | +- `es` - Español (Spanish) |
| 122 | +- `pt` - Português (Portuguese) |
| 123 | +- `ru` - Русский (Russian) |
| 124 | + |
| 125 | +**Output Example:** |
| 126 | + |
| 127 | +``` |
| 128 | +🌐 Translation Assistant for zh-Hans |
| 129 | +
|
| 130 | +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ |
| 131 | +📝 Translation Task |
| 132 | +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ |
| 133 | +
|
| 134 | +Target Language: 简体中文 (Simplified Chinese) |
| 135 | +Entries to translate: 15 |
| 136 | +
|
| 137 | +⚠ Translation Guidelines: |
| 138 | + 1. Preserve brand names: "AI Coding Stack", "Claude Code" |
| 139 | + 2. Keep placeholders intact: {count}, {name}, ${variable} |
| 140 | + 3. Don't translate URLs and file paths |
| 141 | + 4. Maintain consistent terminology |
| 142 | +
|
| 143 | +Content to translate: |
| 144 | +
|
| 145 | +{ |
| 146 | + "pages.home.title": "Welcome to AI Coding Stack", |
| 147 | + "pages.home.description": "Discover the best AI coding tools", |
| 148 | + ... |
| 149 | +} |
| 150 | +``` |
| 151 | + |
| 152 | +--- |
| 153 | + |
| 154 | +## File Structure |
| 155 | + |
| 156 | +``` |
| 157 | +.claude/skills/i18n/ |
| 158 | +├── SKILL.md # This documentation |
| 159 | +└── scripts/ |
| 160 | + ├── sync.mjs # Synchronization script |
| 161 | + └── translate.mjs # Translation assistant script |
| 162 | +``` |
| 163 | + |
| 164 | +## Technical Details |
| 165 | + |
| 166 | +**Language:** Node.js (ES Modules) |
| 167 | +**Dependencies:** Built-in Node.js modules only (`fs`, `path`) |
| 168 | +**JSON Format:** 2-space indentation, trailing newline |
| 169 | +**Encoding:** UTF-8 |
| 170 | + |
| 171 | +### How Keys Are Compared |
| 172 | + |
| 173 | +The scripts use recursive traversal to handle nested JSON structures. Keys are compared using dot notation: |
| 174 | + |
| 175 | +```json |
| 176 | +{ |
| 177 | + "pages": { |
| 178 | + "home": { |
| 179 | + "title": "Welcome" |
| 180 | + } |
| 181 | + } |
| 182 | +} |
| 183 | +``` |
| 184 | + |
| 185 | +Becomes: `pages.home.title = "Welcome"` |
| 186 | + |
| 187 | +### Adding a New Language |
| 188 | + |
| 189 | +1. Add the locale to `src/i18n/config.ts`: |
| 190 | + |
| 191 | +```typescript |
| 192 | +export const locales = ['en', 'zh-Hans', 'ja'] as const; // Add 'ja' |
| 193 | +``` |
| 194 | + |
| 195 | +2. Create an empty JSON file or copy `en.json`: |
| 196 | + |
| 197 | +```bash |
| 198 | +cp messages/en.json messages/ja.json |
| 199 | +``` |
| 200 | + |
| 201 | +3. Run sync to ensure structure matches: |
| 202 | + |
| 203 | +``` |
| 204 | +Please run the i18n sync command |
| 205 | +``` |
| 206 | + |
| 207 | +4. Run translate to generate translation tasks: |
| 208 | + |
| 209 | +``` |
| 210 | +Please run the i18n translate command for ja |
| 211 | +``` |
| 212 | + |
| 213 | +## Best Practices |
| 214 | + |
| 215 | +1. **Always run `sync` before `translate`** to ensure all keys exist |
| 216 | +2. **Make changes to `en.json` first**, then sync other languages |
| 217 | +3. **Review translations** for context accuracy, especially technical terms |
| 218 | +4. **Use Git** to track changes and review diffs before committing |
| 219 | +5. **Keep brand names consistent** across all languages |
| 220 | +6. **Test translations** in the actual UI to verify formatting and length |
| 221 | + |
| 222 | +## Troubleshooting |
| 223 | + |
| 224 | +**Problem:** Script says "file not found" |
| 225 | + |
| 226 | +- **Solution:** Ensure you're running from project root |
| 227 | +- Check that `messages/` directory exists |
| 228 | + |
| 229 | +**Problem:** Keys are out of sync after adding new content |
| 230 | + |
| 231 | +- **Solution:** Run `sync` command to update all language files |
| 232 | + |
| 233 | +**Problem:** Translation contains placeholders like `{0}` instead of `{count}` |
| 234 | + |
| 235 | +- **Solution:** Verify the English source uses named placeholders, re-translate |
| 236 | + |
| 237 | +**Problem:** Some text appears in English in the translated app |
| 238 | + |
| 239 | +- **Solution:** Run `translate` to find missing translations, check for English fallbacks |
| 240 | + |
| 241 | +## Integration with next-intl |
| 242 | + |
| 243 | +This skill is designed to work with the project's `next-intl` setup: |
| 244 | + |
| 245 | +```typescript |
| 246 | +// src/i18n/request.ts |
| 247 | +export default getRequestConfig(async ({ locale }) => ({ |
| 248 | + messages: (await import(`../../messages/${locale}.json`)).default, |
| 249 | +})); |
| 250 | +``` |
| 251 | + |
| 252 | +The JSON files are loaded dynamically based on the current locale. |
| 253 | + |
| 254 | +## License |
| 255 | + |
| 256 | +This skill is part of the AI Coding Stack project and follows the project's Apache 2.0 license. |
0 commit comments