I18n
Open registry of community-contributed AI coding skills (SKILL.md files) — daily-synced to skills-hub.ai. Install across Claude Code, Cursor, Codex CLI, Windsurf, Copilot, and any MCP-compatible tool with one command.
npx -y skills add tinh2/skills-hub-registry --skill i18nAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 8 stars8 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
Set up internationalization by extracting all hardcoded user-facing strings to locale files. Auto-detects framework (Flutter, Next.js, React, Vue, Angular, iOS, Android) and configures the appropriate i18n library (react-intl, next-intl, vue-i18n, flutter_localizations, NSLocalizedString, strings.xml), generates namespaced translation keys with dot notation, handles pluralization via ICU MessageFormat, sets up date/number/currency formatting per locale, adds RTL layout support for Arabic and Hebrew, and replaces every hardcoded string with translation function calls. Use when you need to add multi-language support, extract hardcoded strings, set up locale files, configure translation workflows, handle pluralization, or add RTL support.
SKILL.md
15.7 KB, as published. Nobody here has run it
You are in AUTONOMOUS MODE. Do NOT ask questions. Execute the full pipeline below without pausing for user input. Make reasonable decisions using sensible defaults.
PURPOSE: Set up complete internationalization (i18n) for the current project. Auto-detect the framework, scan for all hardcoded user-facing strings, extract them to locale files, install and configure the appropriate i18n library, and handle pluralization, interpolation, date/number formatting, and RTL layout support.
INPUT: $ARGUMENTS
The user may specify:
- Target locales -- e.g., "en,es,fr,de,ja,ar" (default: "en" as base locale).
- A specific i18n library preference.
- Scope -- specific directories or screens to process.
- RTL support -- explicitly request Arabic/Hebrew layout handling. If no arguments, set up English as the base locale with extraction of all hardcoded strings.
============================================================ PHASE 1 -- FRAMEWORK AND I18N LIBRARY DETECTION
Detect the framework and determine the appropriate i18n library:
| Indicator | Framework | I18n Library |
|---|---|---|
| pubspec.yaml | Flutter | flutter_localizations + intl / easy_localization |
| next.config.* with i18n or package.json with "next" | Next.js | next-intl or next-i18next |
| package.json with "react" (no next) | React | react-intl (FormatJS) or react-i18next |
| package.json with "vue" | Vue | vue-i18n |
| package.json with "@angular/core" | Angular | @angular/localize or ngx-translate |
| package.json with "svelte" | Svelte | svelte-i18n |
| Podfile or *.xcodeproj | iOS (Swift) | NSLocalizedString + Localizable.strings |
| build.gradle with android | Android (Kotlin) | strings.xml resources |
Check for existing i18n setup:
- Existing locale files (en.json, messages_en.arb, Localizable.strings)
- Existing i18n library in dependencies
- Existing translation function usage (t(), $t(), intl.message, etc.)
If an i18n library is already configured, extend it rather than replacing it.
Record: FRAMEWORK, I18N_LIBRARY, LOCALE_DIR, BASE_LOCALE, TARGET_LOCALES
============================================================ PHASE 2 -- STRING EXTRACTION SCAN
Scan the entire source tree for hardcoded user-facing strings.
Step 2.1 -- Identify User-Facing Strings
Search for strings that are displayed to users:
- Text content: String literals inside Text(), <p>, <span>, <h1-h6>, <label>, <button>, placeholder, title, aria-label, alt text, tooltip, snackbar, toast, dialog content
- Error messages: Strings in error handlers, validation messages, catch blocks
- Labels: Form labels, button text, navigation items, tab labels, menu items
- Status text: Loading messages, empty states, success/failure messages
- Notifications: Push notification titles and bodies, in-app alerts
For each string found, record:
- The string value
- File path and line number
- Context (button label, heading, body text, error message, placeholder, etc.)
- Whether it contains dynamic values that need interpolation
Step 2.2 -- Exclude Non-User-Facing Strings
Do NOT extract:
- Log messages (console.log, logger.info, print for debug)
- Code identifiers (route paths, CSS class names, enum values)
- API endpoints and URLs
- Environment variable names
- Test assertions and test data
- Comments and documentation
- String constants used only for programmatic logic (switch cases, map keys)
Step 2.3 -- Generate Translation Key Map
For each extracted string, generate a namespaced translation key:
- Use dot-notation namespacing:
screen.section.element - Examples:
- "Save Changes" on profile screen ->
profile.actions.save - "No items found" empty state ->
items.empty.title - "Are you sure?" delete dialog ->
common.dialog.confirmDelete - "{{count}} items selected" ->
items.selectedCount(with interpolation)
- "Save Changes" on profile screen ->
Group keys by screen/feature for maintainability.
Use a common namespace for strings reused across screens (OK, Cancel, Save, Delete, etc.).
Produce the key map:
| Key | English Value | Context | Interpolation | File |
|---|
============================================================ PHASE 3 -- LOCALE FILE GENERATION
Step 3.1 -- Create Base Locale File
Generate the locale file in the format appropriate for the detected library:
JSON format (react-intl, next-intl, vue-i18n, svelte-i18n):
Create src/locales/en.json or messages/en.json:
{
"common": {
"actions": {
"save": "Save",
"cancel": "Cancel",
"delete": "Delete"
}
},
"profile": {
"title": "My Profile",
"actions": {
"save": "Save Changes"
}
}
}
ARB format (Flutter):
Create lib/l10n/app_en.arb:
{
"@@locale": "en",
"commonSave": "Save",
"@commonSave": { "description": "Save action button" },
"itemCount": "{count, plural, =0{No items} =1{1 item} other{{count} items}}",
"@itemCount": { "description": "Item count with pluralization", "placeholders": { "count": { "type": "int" } } }
}
Localizable.strings (iOS):
Create en.lproj/Localizable.strings.
strings.xml (Android):
Create res/values/strings.xml.
Step 3.2 -- Handle Interpolation
Convert strings with dynamic values to use the library's interpolation syntax:
- react-intl:
{count} itemsor ICU format{count, plural, one {# item} other {# items}} - next-intl:
{count} items - vue-i18n:
{count} itemsor@:common.save - Flutter intl:
{count, plural, =0{No items} =1{1 item} other{{count} items}} - i18next:
{{count}} itemswithcountoption
Step 3.3 -- Handle Pluralization
Identify strings that represent countable items and apply plural rules:
- English: one/other
- Languages with more forms (e.g., Arabic has zero/one/two/few/many/other)
Use ICU MessageFormat where the library supports it.
Step 3.4 -- Generate Target Locale Files
For each target locale beyond the base:
- Create the locale file with the same key structure.
- Copy English values as placeholders with a
[TRANSLATE]prefix. - Set common values that are universal (OK, Email, etc.) to their known translations.
Example: src/locales/es.json with "commonSave": "[TRANSLATE] Save".
Commit: "feat(i18n): generate locale files with extracted strings"
============================================================ PHASE 4 -- I18N LIBRARY SETUP
Step 4.1 -- Install Dependencies
Install the i18n library and any required dependencies:
- react-intl:
npm install react-intl - next-intl:
npm install next-intl - vue-i18n:
npm install vue-i18n - angular:
ng add @angular/localize - Flutter: Add
flutter_localizations,intlto pubspec.yaml - i18next:
npm install i18next react-i18next
Use the project's package manager (npm/yarn/pnpm based on lockfile).
Step 4.2 -- Configure Provider/Plugin
Set up the i18n provider at the application root:
React/Next.js (react-intl):
- Create
src/i18n/config.tswith locale detection and message loading - Wrap the app root with
<IntlProvider> - Configure locale detection from browser or URL
Next.js (next-intl):
- Update
next.config.*with i18n locale configuration - Create middleware for locale routing
- Set up
NextIntlClientProviderin root layout
Vue:
- Create
src/i18n/index.tswith createI18n configuration - Register plugin in main app entry
Flutter:
- Add
localizationsDelegatesandsupportedLocalesto MaterialApp - Generate localization files with
flutter gen-l10n - Create
l10n.yamlconfiguration file
Angular:
- Configure
angular.jsonwith i18n locales - Set up LOCALE_ID provider
Step 4.3 -- Configure Date and Number Formatting
Set up locale-aware formatting:
- Dates: Use Intl.DateTimeFormat (web) or DateFormat (Flutter) with locale parameter
- Numbers: Use Intl.NumberFormat (web) or NumberFormat (Flutter) with locale parameter
- Currency: Configure currency display per locale
- Create formatting utility functions that accept locale as parameter
Step 4.4 -- RTL Layout Support (if Arabic, Hebrew, or Urdu in target locales)
If any RTL locale is requested:
- CSS: Add
[dir="rtl"]selectors or use logical properties (margin-inline-startinstead ofmargin-left) - Flutter: Wrap directional widgets with
Directionalityor useTextDirection.rtl - Next.js: Set
dirattribute on<html>based on locale - Configure text alignment to use
start/endinstead ofleft/right - Mirror horizontal icons (arrows, chevrons) for RTL
- Test that layouts do not break with RTL text direction
Commit: "feat(i18n): configure i18n library with locale detection and formatting"
============================================================ PHASE 5 -- STRING REPLACEMENT
Replace all hardcoded strings in the codebase with translation function calls:
Step 5.1 -- Replace Strings
For each extracted string, replace the hardcoded value with the i18n function:
- react-intl:
<FormattedMessage id="key" />orintl.formatMessage({ id: 'key' }) - next-intl:
t('key')or<NextIntlClientProvider> - vue-i18n:
{{ $t('key') }}ort('key')in setup - Flutter:
AppLocalizations.of(context)!.keyName - i18next:
t('key')or<Trans i18nKey="key" /> - Angular:
{{ 'key' | translate }}or$localize
Step 5.2 -- Handle Interpolated Strings
Replace strings with dynamic values:
// Before
`Welcome, ${user.name}!`
// After (react-intl)
intl.formatMessage({ id: 'greeting.welcome' }, { name: user.name })
// After (Flutter)
AppLocalizations.of(context)!.greetingWelcome(user.name)
Step 5.3 -- Handle Conditional Strings
Replace pluralized or conditional strings:
// Before
`${count} item${count !== 1 ? 's' : ''}`
// After (react-intl with ICU)
intl.formatMessage({ id: 'items.count' }, { count })
// In locale file: "{count, plural, one {# item} other {# items}}"
Commit per screen or feature module:
- "fix(i18n): extract strings from [screen/module] to locale keys"
============================================================ PHASE 6 -- VERIFICATION
Step 6.1 -- Static Analysis
Run the appropriate linter/analyzer:
- Flutter:
flutter analyzeandflutter gen-l10n - TypeScript:
tsc --noEmit - Framework linter if configured
Fix all errors introduced by the i18n integration.
Step 6.2 -- String Coverage Audit
Re-scan the codebase for any remaining hardcoded user-facing strings:
- Report strings found vs strings extracted
- Coverage percentage
- List any intentionally skipped strings with rationale
Step 6.3 -- Locale File Validation
Verify locale files:
- All keys present in base locale exist in every target locale
- No orphaned keys (keys in locale file not used in code)
- ICU message syntax is valid
- Interpolation placeholders match between locales
============================================================ SELF-HEALING VALIDATION (max 3 iterations)
After completing fixes, re-validate:
- Re-run the specific UX/accessibility checks that originally found issues.
- Run the project's test suite to verify fixes didn't break functionality.
- Run build/compile to confirm no breakage.
- If new issues surfaced from fixes, add them to the fix queue.
- Repeat up to 3 iterations.
STOP when:
- Zero Critical/High issues remain
- Build and tests pass
IF STILL FAILING after 3 iterations:
- Document remaining issues with full context
============================================================ OUTPUT
## I18n Setup Complete
### Framework: [detected]
### I18n Library: [library]
### Base Locale: [locale]
### Target Locales: [list]
### Files Created/Modified
| File | Purpose |
|------|---------|
| [path] | [description] |
### String Extraction Summary
| Category | Count |
|----------|-------|
| Total strings found | N |
| Strings extracted | N |
| Strings skipped (non-user-facing) | N |
| Unique translation keys | N |
| Common/shared keys | N |
| Keys with interpolation | N |
| Keys with pluralization | N |
### Locale File Status
| Locale | Keys | Translated | Needs Translation |
|--------|------|-----------|-------------------|
| en | N | N (base) | 0 |
| es | N | N | N |
### Coverage
- Screens processed: N/N
- Strings replaced: N/N (N%)
- Remaining hardcoded: N (with rationale)
============================================================ NEXT STEPS
After i18n setup:
- Translate the
[TRANSLATE]-prefixed values in each target locale file. - "Run
/uxto audit UX quality including localized content." - "Run
/responsiveto verify layouts do not break with longer translated strings." - "Run
/design-systemto ensure text styles accommodate variable-length translations." - For professional translations, export locale files to a translation management platform (Crowdin, Lokalise, Phrase).
============================================================ SELF-EVOLUTION TELEMETRY
After producing output, record execution metadata for the /evolve pipeline.
Check if a project memory directory exists:
- Look for the project path in
~/.claude/projects/ - If found, append to
skill-telemetry.mdin that memory directory
Entry format:
### /i18n — {{YYYY-MM-DD}}
- Outcome: {{SUCCESS | PARTIAL | FAILED}}
- Self-healed: {{yes — what was healed | no}}
- Iterations used: {{N}} / {{N max}}
- Bottleneck: {{phase that struggled or "none"}}
- Suggestion: {{one-line improvement idea for /evolve, or "none"}}
Only log if the memory directory exists. Skip silently if not found. Keep entries concise — /evolve will parse these for skill improvement signals.
============================================================ DO NOT
- Do NOT extract log messages, debug strings, or code-only identifiers -- these are not user-facing.
- Do NOT use auto-translation APIs to fill in target locales -- use placeholder markers instead.
- Do NOT create deeply nested key structures beyond 3 levels -- keep keys flat and scannable.
- Do NOT use string concatenation for translated text -- use interpolation placeholders.
- Do NOT hardcode locale names in conditional logic -- use the i18n library's locale detection.
- Do NOT skip pluralization for countable items -- different languages have different plural rules.
- Do NOT remove the original English strings from code comments -- they serve as context for translators.
- Do NOT overwrite existing locale files without reading them first -- merge new keys into existing files.
- Do NOT assume left-to-right layout -- use logical CSS properties and directional-aware widgets.