AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

I18n

skill-int2t05-engineering-skills-i18n · by int2t05

Use when internationalizing an application — message extraction, ICU/MessageFormat, locale routing, RTL layout, pluralization/gender, and locale-aware formatting. Triggers on "i18n", "localization", "l10n", "RTL", "国际化", "本地化", "多语言".

No reviews yet
0 installs
23 views
0.0% view→install

Install

$ agentstack add skill-int2t05-engineering-skills-i18n

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-int2t05-engineering-skills-i18n)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
19d ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of I18n? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Internationalization (i18n)

Internationalization is not translation — it is the engineering discipline of making an application locale-aware so translation is a content change, not a code change. Hardcoded strings, locale-blind formatting, and LTR-only layouts all become bugs the moment a second locale is needed. Build the scaffolding before the second locale arrives, not after.

When to use

  • Preparing an application for multiple locales (message extraction, locale routing, formatting)
  • Adding RTL support or locale-specific pluralization/gender rules
  • Auditing an existing app for hardcoded strings or locale-blind formatting
  • Triggers on "i18n", "localization", "l10n", "RTL", "国际化", "本地化", "多语言"

Not for: frontend visual design (use frontend-design); API contract design (use api-design). i18n is a cross-cutting implementation discipline touching frontend, backend, and build tooling.

Steps

1. Audit the locale surface

Before writing code, find every locale-sensitive surface in the application:

  • Hardcoded user-facing strings (UI labels, error messages, email templates, push notifications)
  • Formatted values: dates, times, numbers, currencies, percentages, units
  • Pluralization and gender-dependent phrasing
  • Layout assumptions: LTR-only CSS, fixed-width containers, text concatenation
  • Locale-affecting config: timezone handling, first-day-of-week, calendar system

Verify: the audit produces a list of locale-sensitive surfaces grouped by type, not a vague "needs translation."

2. Extract messages

Replace every hardcoded string with a message ID resolved through an i18n library. Messages live in locale files keyed by ID, not inline:

  • Use the framework's i18n library (react-intl, i18next, FormatJS, vue-i18n, or equivalent)
  • Message IDs are descriptive (user.profile.edit_button), not positional (btn_3)
  • Leave source-locale strings as the fallback; never leave a missing-key hole in production
  • Extract programmatically (CLI extractors) where the framework supports it — manual extraction

drifts

Verify: grep for user-facing literals in components returns only IDs; no hardcoded strings reach the user.

3. Choose message format and handle pluralization

Use ICU MessageFormat — it is the standard for handling the grammar that varies across locales (plurals, gender, select). Avoid string concatenation and naive plural rules (if count === 1); they fail across locales:

  • Pluralization: ICU plural syntax handles the 6 CLDR plural categories (zero, one, two, few,

many, other) — English needs two, Arabic needs all six

  • Gender / select: ICU select syntax for gendered or context-dependent phrasing
  • Interpolation: named placeholders, never positional — translators reorder sentences
  • Rich text: embed component placeholders (links, bold) via ICU rich-text or the library's

component-interpolation, not by splitting strings around tags (splitting breaks translation)

Verify: every message with a count uses ICU plural syntax; no count + " items" concatenation.

4. Set up locale routing and detection

Decide how a user's locale is determined and how it maps to routes:

  • Detection order: explicit user preference (account setting) → URL path/query →

Accept-Language header → geo (with caution — geo ≠ language) → default

  • Persistence: store the choice (cookie / account) so it survives navigation
  • Routing: locale-prefixed routes (/en/..., /ar/...) for SEO and shareability; or

path-less with client detection for app-only surfaces — choose deliberately

  • SSR / hydration: the server must render in the detected locale, not render a default then

flash-correct on the client (hydration mismatch = broken UX)

  • Server-side message loading (RSC): in App Router / RSC frameworks, load only the request's

locale messages on the server (per-locale bundle split, not an all-locales bundle); bind locale per-request (setRequestLocale-style, never a module global); keep server-only messages out of the client bundle. See [references/server-i18n.md](references/server-i18n.md) for the full pattern.

Verify: locale detection follows the documented order; the initial server render matches the client locale (no flash).

5. Handle formatting and layout

Locale-aware formatting for every user-facing value:

  • Dates/times: format via Intl.DateTimeFormat or the i18n library; honor timezone, calendar,

and locale-specific ordering. Never hand-build date strings.

  • Numbers/currencies: Intl.NumberFormat; currencies need the locale (symbol placement) AND the

currency code (¥ in Japan vs. ¥ in China).

  • RTL: CSS logical properties (margin-inline-start, not margin-left); dir attribute on

the root; mirror icons and directional layouts. Test in an RTL locale, not by eyeballing.

  • Text length: translated text is 30–50% longer than English (German) or shorter (Chinese);

layouts must flex, not truncate. No fixed-width buttons.

Verify: dates/numbers render correctly in at least LTR + RTL locales; logical properties used; layout survives 140% text expansion.

6. Test across locales

Run the app in a non-source locale — preferably an RTL one (Arabic, Hebrew) — to surface the bugs that source-locale testing hides:

  • Missing translations render as IDs or fallback (never blank)
  • Pluralization correct for the locale's plural rules
  • RTL layout mirrors correctly; no overflow or overlap
  • Formatting (date, number, currency) matches the locale
  • E2E tests parameterized by locale where feasible

Verify

  • [ ] No hardcoded user-facing strings in components (grep confirms)
  • [ ] All messages extracted to locale files with descriptive IDs
  • [ ] Pluralization uses ICU MessageFormat; no concatenation
  • [ ] Locale detection documented; SSR matches client locale (no flash)
  • [ ] Only the request's locale messages ship to the client (no all-locales bundle); locale is

request-scoped, not a module global

  • [ ] Dates/numbers/currencies via Intl APIs; correct in LTR + RTL
  • [ ] CSS uses logical properties; layout survives 140% text expansion
  • [ ] App tested in at least one RTL locale; no overflow, overlap, or missing translations

Red flags: if (count === 1) "item" else "items"; string concatenation to build sentences; hand-built date formatting (day + "/" + month); margin-left in a layout that needs RTL; fixed-width containers with text; positional placeholders; splitting a string around an inline link; assuming Accept-Language is the right detection (users override); rendering a default locale server-side then correcting on the client; a module-level currentLocale variable under concurrent requests; import messages from './messages' where the index re-exports every locale (ships all locales to every client).

References

  • [${CLAUDEPLUGINROOT}/references/engineering-principles.md](${CLAUDEPLUGINROOT}/references/engineering-principles.md) — shared discipline (surface assumptions, surgical scope, verify don't assume)
  • [references/i18n-checklist.md](references/i18n-checklist.md) — locale-surface audit template, ICU syntax reference, RTL conversion checklist, locale-detection patterns, test-locale matrix
  • [references/server-i18n.md](references/server-i18n.md) — RSC / App Router message loading, per-locale bundle splitting, request-scoped locale, hydration alignment

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.