Skip to content
Back to skills

I18n

ASecurity

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.

  • 32,950 stars
  • 0 votes
  • 0 copies
  • 3 views
  • Added February 7, 2026
developmentgobashreactapi

Works with

  • api

Security analysis

A100/100

Scanned February 10, 2026

npx -y skills add iOfficeAI/AionUi --skill i18n --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of I18n?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for I18n
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/iofficeai-i18n/badge)](https://www.skillsdirectory.com/skills/iofficeai-i18n)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: i18n
description: |
  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.
---

# i18n Skill

Standards and workflow for internationalization. All user-visible text must use i18n.

**Announce at start:** "I'm using i18n skill to ensure proper internationalization."

## File Structure

```
src/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
```

## Key Naming Convention

**IMPORTANT**: New i18n keys MUST use flat dot-notation format.

Format: `<module>.<feature>.<detail>`

### Rules

| Level   | Description            | Examples                                 |
| ------- | ---------------------- | ---------------------------------------- |
| Module  | Page or major feature  | `cron`, `chat`, `settings`, `auth`       |
| Feature | Specific functionality | `form`, `list`, `modal`, `sidebar`       |
| Detail  | Specific text purpose  | `title`, `placeholder`, `label`, `empty` |

### Examples

```
✓ cron.form.title
✓ cron.form.namePlaceholder
✓ cron.list.emptyState
✓ settings.llm.apiKeyRequired

✗ cronFormTitle           (missing dots)
✗ CRON.FORM.TITLE         (wrong case)
```

### Flat vs Nested Structure

```json
// ✅ 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": "..."
    }
  }
}
```

**Rationale:**

- Flat keys are searchable in codebase (see `t('cron.form.title')`, search directly)
- Easier to verify sync across locale files
- Avoids deep nesting confusion

### Common Suffixes

| Suffix              | Usage                |
| ------------------- | -------------------- |
| `title`             | Section/page titles  |
| `placeholder`       | Input placeholders   |
| `label`             | Form labels          |
| `button` / `action` | Button text          |
| `success` / `error` | Status messages      |
| `confirm`           | Confirmation dialogs |
| `empty`             | Empty state messages |
| `loading`           | Loading states       |
| `tooltip`           | Tooltip text         |

### Shared Keys

Use `common.*` for reusable text:

```json
{
  "common.save": "Save",
  "common.cancel": "Cancel",
  "common.confirm": "Confirm",
  "common.delete": "Delete",
  "common.loading": "Loading..."
}
```

## Adding New Text Workflow

### Step 1: Check Existing Keys

Before adding new key, search for similar existing keys:

```bash
grep -r "keyword" src/renderer/i18n/locales/
```

### Step 2: Add to ALL Locale Files

**CRITICAL:** Must add to all 5 files simultaneously.

```bash
# 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   # Korean
```

### Step 3: Use in Component

```tsx
import { useTranslation } from 'react-i18next';

function MyComponent() {
  const { t } = useTranslation();

  return <button>{t('module.feature.action')}</button>;
}
```

### Step 4: Verify Sync

After adding, verify all files have the new keys.

## Sync Checking

### Before Commit

Always verify key sync across all locale files:

```bash
# 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)
```

### Fix Sync Issues

If keys are out of sync:

1. Identify missing keys from diff output
2. Add missing keys to appropriate files
3. Re-run diff to verify

## Hardcoded String Detection

### Prohibited Patterns

Never use hardcoded Chinese/English text in JSX:

```tsx
// ❌ 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')}
```

### Exceptions

Comments and internal logs are allowed:

```tsx
// This is a comment, Chinese is OK
console.log('Debug info'); // OK for logs
```

## zh-TW Maintenance

### Auto-conversion Safe

Most terms can be auto-converted from zh-CN:

- 设置 → 設置
- 删除 → 刪除
- 确认 → 確認

### Manual Adjustment Required

Some terms need manual review:

| zh-CN | zh-TW | Notes          |
| ----- | ----- | -------------- |
| 视频  | 影片  | Different term |
| 软件  | 軟體  | Different term |
| 信息  | 訊息  | Different term |
| 默认  | 預設  | Different term |

## Interpolation

### Variables

```json
{
  "greeting": "Hello, {{name}}!",
  "itemCount": "{{count}} items"
}
```

```tsx
t('greeting', { name: 'User' });
t('itemCount', { count: 5 });
```

### HTML in Translations

Use Trans component for complex markup:

```tsx
import { Trans } from 'react-i18next';

<Trans i18nKey='cron.countdown'>
  Task <strong>{{ taskName }}</strong> in <span>{{ countdown }}</span>
</Trans>;
```

## Quick Checklist

Before submitting code with new text:

- [ ] All user-visible text uses `t()` function
- [ ] New keys use flat `module.feature.detail` format
- [ ] New keys added to ALL 5 locale files
- [ ] No hardcoded Chinese/English in JSX
- [ ] zh-TW reviewed for term differences
- [ ] ja-JP and ko-KR translations added (or marked TODO)

## Common Mistakes

| Mistake                        | Correct                          |
| ------------------------------ | -------------------------------- |
| Adding key to only one file    | Add to all 5 files               |
| Using nested structure for new | Use flat `module.feature.detail` |
| Using `t("New Chat")`          | Define key: `t("chat.new")`      |
| Inline Chinese in JSX          | Use `t()` with defined key       |
| Forgetting interpolation       | Use `{{variable}}` syntax        |

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.