# I18N Translate

> Extract user-facing strings from source code into locale files, then translate them across locales. Supports JSON, YAML, .po, and Flutter .arb formats.

- Skill: `kasimmj/i18n-translate` (Agent Skill)
- Install (CLI): `npx skillmds@latest add kasimmj/i18n-translate`
- Raw SKILL.md: https://api.skillmd.com/api/skills/kasimmj/i18n-translate/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: MIT
- Author: kasimmj (https://skillmd.com/u/kasimmj)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/kasimmj/i18n-translate

---


# 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 files
- `next-intl`, `next-i18next` → JSON or messages/
- `vue-i18n` → JSON or YAML
- Flutter — `.arb` files
- Django — `.po` files 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:
```jsx
// 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-retranslate` if 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 })`).

