i18n Translate Skill
You are setting up or extending internationalization (i18n) for the project.
Step 1 — Detect the i18n framework
Look for:
i18next.config.*,react-i18next→ JSON locale filesnext-intl,next-i18next→ JSON or messages/vue-i18n→ JSON or YAML- Flutter —
.arbfiles - Django —
.pofiles via gettext - Rails —
config/locales/*.yml
If nothing exists, propose a setup based on the framework.
Step 2 — Extract strings
Scan the source for hardcoded user-facing strings:
- JSX/TSX: text inside elements, button labels, placeholders, alt text
- HTML templates: text content, attributes
- Markdown content in code (rare but possible)
Skip:
- Log messages (dev-facing)
- Test fixtures
- Strings already wrapped in
t(),$t(),gettext(),tr(), etc.
For each extracted string, generate a stable key like <screen>.<element>.<action>:
LoginScreen.submitButton.label = "Sign In"
LoginScreen.emailField.placeholder = "Enter your email"
Step 3 — Translate
For each target locale, translate the values:
- Arabic (
ar) — RTL. Watch out for proper plurals (Arabic has 6). - Spanish (
es) — formal vs. informal. Default to formal (usted). - French (
fr) — match gender of nouns. Watch agreement. - Japanese (
ja) — no plurals, but politeness levels matter. - Chinese (
zh-CN/zh-TW) — Simplified vs. Traditional.
If you're translating to Arabic specifically, also configure:
- RTL flag in the framework
- Mirror padding/margins (e.g.,
padding-left→padding-inline-start)
Step 4 — Replace strings in source
Replace hardcoded strings with the i18n call:
// before
<button>Sign In</button>
// after
<button>{t('LoginScreen.submitButton.label')}</button>
Step 5 — Output
Generate:
- One updated locale file per language
- A patch/diff for the source files
- A short summary: "X strings extracted, Y locales updated, Z files modified"
When NOT to use
- The project has no UI (CLI tools, libraries)
- Strings are already extracted but need re-translation (use
i18n-retranslateif available)
Failure modes
- ⚠️ Machine translations are a starting point. Recommend a human review for production.
- ⚠️ Watch for context-dependent words ("post" — verb? noun? blog post? mail?). When ambiguous, ask the user.
- ⚠️ Plural forms: don't fake them. Use the framework's plural API (
t('items.count', { count: n })).