agentsclimarketplace

I18n

Skill tinh2/skills-hub-registry/ux/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.

Install
npx -y skills add tinh2/skills-hub-registry --skill i18n

Assembled 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:

  1. Target locales -- e.g., "en,es,fr,de,ja,ar" (default: "en" as base locale).
  2. A specific i18n library preference.
  3. Scope -- specific directories or screens to process.
  4. 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:

IndicatorFrameworkI18n Library
pubspec.yamlFlutterflutter_localizations + intl / easy_localization
next.config.* with i18n or package.json with "next"Next.jsnext-intl or next-i18next
package.json with "react" (no next)Reactreact-intl (FormatJS) or react-i18next
package.json with "vue"Vuevue-i18n
package.json with "@angular/core"Angular@angular/localize or ngx-translate
package.json with "svelte"Sveltesvelte-i18n
Podfile or *.xcodeprojiOS (Swift)NSLocalizedString + Localizable.strings
build.gradle with androidAndroid (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)

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:

KeyEnglish ValueContextInterpolationFile

============================================================ 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} items or ICU format {count, plural, one {# item} other {# items}}
  • next-intl: {count} items
  • vue-i18n: {count} items or @:common.save
  • Flutter intl: {count, plural, =0{No items} =1{1 item} other{{count} items}}
  • i18next: {{count}} items with count option

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:

  1. Create the locale file with the same key structure.
  2. Copy English values as placeholders with a [TRANSLATE] prefix.
  3. 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, intl to 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.ts with 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 NextIntlClientProvider in root layout

Vue:

  • Create src/i18n/index.ts with createI18n configuration
  • Register plugin in main app entry

Flutter:

  • Add localizationsDelegates and supportedLocales to MaterialApp
  • Generate localization files with flutter gen-l10n
  • Create l10n.yaml configuration file

Angular:

  • Configure angular.json with 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-start instead of margin-left)
  • Flutter: Wrap directional widgets with Directionality or use TextDirection.rtl
  • Next.js: Set dir attribute on <html> based on locale
  • Configure text alignment to use start/end instead of left/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" /> or intl.formatMessage({ id: 'key' })
  • next-intl: t('key') or <NextIntlClientProvider>
  • vue-i18n: {{ $t('key') }} or t('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 analyze and flutter 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:

  1. Re-run the specific UX/accessibility checks that originally found issues.
  2. Run the project's test suite to verify fixes didn't break functionality.
  3. Run build/compile to confirm no breakage.
  4. If new issues surfaced from fixes, add them to the fix queue.
  5. 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 /ux to audit UX quality including localized content."
  • "Run /responsive to verify layouts do not break with longer translated strings."
  • "Run /design-system to 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.md in 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.

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.