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.
>_
Quick Install
npxskills add iofficeai/aionui--skill i18n
Instructions
Loading…
Tags & Topics
aiai-agentgeminigemini-clillmchat
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."
IMPORTANT: Read Config First
Before doing any i18n work, always read src/common/config/i18n-config.json to get the current list of supported languages and modules. Never assume a fixed number — languages and modules may have been added or removed since this skill was written.
cat src/common/config/i18n-config.json
This file is the single source of truth. All scripts, runtime code, and this workflow depend on it.
File Structure
src/common/config/i18n-config.json # Single source of truth: languages, modules
src/renderer/i18n/
├── index.ts # i18next configuration
├── i18n-keys.d.ts # AUTO-GENERATED — do not edit manually
└── locales/
├── <lang>/ # One directory per language in i18n-config.json
│ ├── index.ts # Barrel import for all modules
│ ├── common.json # One JSON per module in i18n-config.json
│ ├── conversation.json
│ └── ...
└── ...
Key Facts
Reference language: defined by referenceLanguage in i18n-config.json (currently en-US)
Supported languages: defined by supportedLanguages array — read the file to get the current list
Modules: defined by modules array — read the file to get the current list
Key Structure
Keys use namespaced dot notation in code: t('module.key') or t('module.nested.key').
Inside each module JSON file, keys can be flat or nested:
Match the module to the feature area. If no module fits, consider whether a new module is needed (see "Adding a New Module" below).
Step 4: Add to ALL Locale Directories
CRITICAL: Every new key must be added to every locale in supportedLanguages. Use this checklist for each key:
en-US/<module>.json — reference language (added in Step 3)
zh-CN/<module>.json — added
zh-TW/<module>.json — added
Any other language listed in src/common/config/i18n-config.json → supportedLanguages — added
A key missing from even one locale will cause node scripts/check-i18n.js to fail in CI.
Step 5: Use in Component
import { useTranslation } from 'react-i18next';
function MyComponent() {
const { t } = useTranslation();
return <button>{t('common.save')}</button>;
}
Step 6: Regenerate Types and Validate
Run these two commands in order — both must pass before committing:
bun run i18n:types # Step A: regenerate i18n-keys.d.ts from reference locale
node scripts/check-i18n.js # Step B: validate structure, keys, and type sync
i18n:types must be run beforecheck-i18n.js — the check validates the generated file
If check-i18n.js exits with errors (❌), fix them before proceeding
If check-i18n.js exits with warnings only (⚠️), review but may proceed
Never commit with a stale i18n-keys.d.ts
Adding a New Module
Add module name to src/common/config/i18n-config.json → modules array
Create <module>.json in every locale directory (read supportedLanguages to know which)
Add import + export in each locale's index.ts
Run bun run i18n:types to regenerate type definitions
Run node scripts/check-i18n.js to validate
Hardcoded String Detection
Prohibited Patterns
Never use hardcoded Chinese/English text in JSX:
// Bad
<span>重命名</span>
<span>Delete</span>
{name || '新对话'}
// Good
<span>{t('common.rename')}</span>
<span>{t('common.delete')}</span>
{name || t('conversation.newConversation')}