Loading...
Loading...
Internationalization (i18n) workflow and standards for managing translations. Use when: (1) Adding new user-facing text, (2) Creating new components with text, (3) Reviewing code for i18n compliance. Features: Key naming conventions, sync checking, hardcoded string detection, translation workflow.
npx skill4agent add iofficeai/aionui i18nsrc/renderer/i18n/
├── index.ts # i18next configuration
└── locales/
├── en-US.json # English (primary)
├── zh-CN.json # Simplified Chinese
├── zh-TW.json # Traditional Chinese
├── ja-JP.json # Japanese
└── ko-KR.json # Korean<module>.<feature>.<detail>| Level | Description | Examples |
|---|---|---|
| Module | Page or major feature | |
| Feature | Specific functionality | |
| Detail | Specific text purpose | |
✓ cron.form.title
✓ cron.form.namePlaceholder
✓ cron.list.emptyState
✓ settings.llm.apiKeyRequired
✗ cronFormTitle (missing dots)
✗ CRON.FORM.TITLE (wrong case)// ✅ GOOD - flat structure (use for NEW keys)
{
"cron.form.title": "Create Scheduled Task",
"cron.form.nameLabel": "Task Name",
"cron.list.empty": "No scheduled tasks"
}
// ❌ AVOID - nested structure (legacy only, do not add new)
{
"cron": {
"form": {
"title": "..."
}
}
}t('cron.form.title')| Suffix | Usage |
|---|---|
| Section/page titles |
| Input placeholders |
| Form labels |
| Button text |
| Status messages |
| Confirmation dialogs |
| Empty state messages |
| Loading states |
| Tooltip text |
common.*{
"common.save": "Save",
"common.cancel": "Cancel",
"common.confirm": "Confirm",
"common.delete": "Delete",
"common.loading": "Loading..."
}grep -r "keyword" src/renderer/i18n/locales/# Files to update:
src/renderer/i18n/locales/en-US.json # English text
src/renderer/i18n/locales/zh-CN.json # Simplified Chinese
src/renderer/i18n/locales/zh-TW.json # Traditional Chinese
src/renderer/i18n/locales/ja-JP.json # Japanese
src/renderer/i18n/locales/ko-KR.json # Koreanimport { useTranslation } from 'react-i18next';
function MyComponent() {
const { t } = useTranslation();
return <button>{t('module.feature.action')}</button>;
}# Quick check - compare line counts (rough indicator)
wc -l src/renderer/i18n/locales/*.json
# Check for flat keys diff between en-US and zh-CN
diff <(grep -oE '"[a-zA-Z0-9_.]+":' src/renderer/i18n/locales/en-US.json | sort -u) \
<(grep -oE '"[a-zA-Z0-9_.]+":' src/renderer/i18n/locales/zh-CN.json | sort -u)// ❌ BAD
<span>重命名</span>
<span>Delete</span>
<button title="更多操作">...</button>
{name || '新对话'}
// ✅ GOOD
<span>{t('common.rename')}</span>
<span>{t('common.delete')}</span>
<button title={t('common.moreActions')}>...</button>
{name || t('chat.newConversation')}// This is a comment, Chinese is OK
console.log('Debug info'); // OK for logs| zh-CN | zh-TW | Notes |
|---|---|---|
| 视频 | 影片 | Different term |
| 软件 | 軟體 | Different term |
| 信息 | 訊息 | Different term |
| 默认 | 預設 | Different term |
{
"greeting": "Hello, {{name}}!",
"itemCount": "{{count}} items"
}t('greeting', { name: 'User' });
t('itemCount', { count: 5 });import { Trans } from 'react-i18next';
<Trans i18nKey='cron.countdown'>
Task <strong>{{ taskName }}</strong> in <span>{{ countdown }}</span>
</Trans>;t()module.feature.detail| Mistake | Correct |
|---|---|
| Adding key to only one file | Add to all 5 files |
| Using nested structure for new | Use flat |
Using | Define key: |
| Inline Chinese in JSX | Use |
| Forgetting interpolation | Use |