agentleFS
nledfordnledford/engineering-review-board/skills/internationalization-localization/SKILL.md

internationalization-localization

Skill11 starsChanged 10 days agoMITView on GitHub

Internationalization and localization guidance, including Project Fluent and Fluent Translation List (.ftl) files. Use when adding, changing, reviewing, or testing localized, multilingual, or localization-ready user-facing text, locale negotiation, translation catalogs, plural/select behavior, localized date/number formatting, or Fluent integrations in JavaScript, TypeScript, PHP, Python, Rust, or web UI. Do not use for fixed-language copyediting with no localization surface. Consult current official documentation for Fluent binding APIs and use security-review plus security-review-evidence when localized content crosses trust boundaries.

The file

Show its rules and text

We split this skill into the rules it gives an agent

26 rules. About 0 are common, 16 are distinctive, and 10 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈16

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 10

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Use this skill when software needs to present text, formatting, or UI behavior for more than one locale.

    line 8
  2. Distinctive:

    Do not use this skill for copyediting a single fixed-language message with no localization surface.

    line 30
  3. Very specific:

    Treat American English (en-US) as the default/source locale unless the repository explicitly defines another source locale.

    line 45
  4. Distinctive:

    Put language decisions in the catalog, not in application string assembly.

    line 53
  5. Distinctive:

    Verify with the repository's parser, linter, typecheck, unit tests, snapshot tests, E2E tests, or build-time catalog validation.

    line 65
  6. Very specific:

    Use stable, semantic message IDs: checkout-submit, profile-greeting, error-network-timeout.

    line 70
  7. Distinctive:

    Prefer complete sentences or complete UI labels.

    line 72
  8. Very specific:

    Use variables/placeables for runtime data: welcome = Welcome, { $user }!

    line 74
  9. Distinctive:

    Keep variable names meaningful and pass typed values where the runtime supports locale-aware number/date formatting.

    line 75
  10. Very specific:

    Use selectors for plurals, gender, grammatical case, or state.

    line 77
  11. Very specific:

    Use CLDR plural categories such as one, few, many, and other instead of hard-coding English assumptions.

    line 88
  12. Distinctive:

    Use terms for reusable product vocabulary and brand names:

    line 92
  13. Distinctive:

    Use parameterized terms only when localizers need grammatical variants, such as case or gender.

    line 99
  14. Distinctive:

    Use attributes to group text for one UI element, including accessible labels:

    line 101
  15. Distinctive:

    Add translator comments for placeholders, ambiguous terms, character limits, tone, variables, and UI context.

    line 109
  16. Very specific:

    Keep .ftl indentation space-based.

    line 111
  17. Very specific:

    Use BCP 47 locale tags such as en-US, es, es-MX, ja, or ja-JP.

    line 116
  18. Very specific:

    Keep en-US complete. Other locales may be partial only if fallback behavior is intentional, visible in tests, and acceptable for the …

    line 120
  19. Distinctive:

    Test long strings, short strings, missing translations, bidirectional content, pseudolocalized text, and accessible names.

    line 126
  20. Distinctive:

    Use local dependency versions and current upstream docs before changing APIs.

    line 133
  21. Distinctive:

    Keep catalog and runtime validation separate.

    line 163
  22. Distinctive:

    Add regression tests near the code that formats messages.

    line 174
  23. Distinctive:

    Use pseudolocalization or long-string fixtures to catch clipped text, concatenation assumptions, and layout coupling.

    line 177
  24. Very specific:

    Do not assume Fluent sanitizes output for every sink.

    line 186
  25. Distinctive:

    Treat translator-controlled markup and attributes as security-sensitive.

    line 189
  26. Very specific:

    When Zod is selected, load zod-engineering.

    line 208

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Internationalization and Localization

Use this skill when software needs to present text, formatting, or UI behavior for more than one locale. Internationalization (i18n) makes the product localizable; localization (l10n) provides locale-specific messages, formats, and conventions.

Project Fluent is a localization system and message syntax designed to let localizers express natural-language complexity such as plurals, gender, case, conjugation, and word order in translation files instead of application code. Fluent resources are usually written as Fluent Translation List (.ftl) files.

Use When

  • Adding or reviewing user-facing strings, message catalogs, locale folders, translation IDs, fallback chains, or locale negotiation.
  • Writing or editing .ftl files, Fluent selectors, variables, terms, attributes, translator comments, or localized number/date formatting.
  • Integrating Project Fluent through fluent.js, python-fluent, fluent-rs, or framework wrappers built on those packages.
  • Testing locale-specific output, fallback behavior, missing translations, pseudolocalization, right-to-left/bidirectional layout, or accessibility text.
  • Implementing or reviewing localized PHP messages, locale negotiation, formatters, Gettext, framework catalogs, or PHP/Smarty rendering boundaries.

Do not use this skill for copyediting a single fixed-language message with no localization surface. Use language engineering skills for implementation mechanics, css-scss-styling for layout and writing-direction styling, api-design for public locale contract design, playwright-e2e for browser-visible localization tests, and documentation-engineering for docs-only localization guidance. This skill owns message design, formatting, fallback, bidi, pseudolocalization, and localization testing.

Workflow

  1. Inspect local conventions first: existing locale directories, source locale, message ID style, extraction/build scripts, package versions, fallback order, tests, and translation review workflow.
  2. Treat American English (en-US) as the default/source locale unless the repository explicitly defines another source locale. Keep source messages clear and complete; do not use sentence fragments that force other languages to copy English grammar.
  3. Decide whether the project needs full i18n or a smaller scoped change. Use Project Fluent when localizers need control over pluralization, grammatical variants, markup overlays, attributes, or cross-language word order; a simpler key/value library may be enough for a prototype or fixed internal tool.
  4. Put language decisions in the catalog, not in application string assembly. Pass structured variables such as counts, dates, names, and states into Fluent; let the locale choose wording and order.
  5. Design fallback before implementation. Typical order is requested locale, language fallback when supported, then en-US. Test missing-message and missing-variable behavior instead of assuming silent success.
  6. Apply the negotiated BCP 47 language and script-aware direction with lang and dir on the document or localized subtree. Use logical CSS properties; do not infer direction from arbitrary user strings.
  7. Consult current official upstream documentation before changing version-sensitive binding APIs, framework adapters, CLI tools, or parser/validator behavior.
  8. Verify with the repository's parser, linter, typecheck, unit tests, snapshot tests, E2E tests, or build-time catalog validation.

Fluent .ftl Authoring Rules

  • Use stable, semantic message IDs: checkout-submit, profile-greeting, error-network-timeout. Avoid IDs that encode English text or UI position.
  • Prefer complete sentences or complete UI labels. Do not concatenate localized fragments in code.
  • Use variables/placeables for runtime data: welcome = Welcome, { $user }!. Keep variable names meaningful and pass typed values where the runtime supports locale-aware number/date formatting.
  • Use selectors for plurals, gender, grammatical case, or state. Always include a default variant marked with *.

    inbox-count =
        { $count ->
            [one] One message
           *[other] { $count } messages
        }
  • Use CLDR plural categories such as one, few, many, and other instead of hard-coding English assumptions. Some languages do not use English-style plural forms; Japanese commonly uses one form where English uses singular and plural; Spanish needs gender and agreement in many messages.
  • Use terms for reusable product vocabulary and brand names:

    -brand-name = ExampleApp
    about-title = About { -brand-name }
  • Use parameterized terms only when localizers need grammatical variants, such as case or gender. Do not expose terms directly as user-facing messages.
  • Use attributes to group text for one UI element, including accessible labels:

    email-input = Email
        .hint = name@example.com
        .aria-label = Email address
  • Add translator comments for placeholders, ambiguous terms, character limits, tone, variables, and UI context. Use group or file comments for broader context.
  • Keep .ftl indentation space-based. Preserve Unicode text. Escape literal braces or leading special characters according to Fluent syntax rules.

Locale and Language Guidance

  • Use BCP 47 locale tags such as en-US, es, es-MX, ja, or ja-JP. Store locale-specific files in predictable paths, for example locales/en-US/app.ftl, locales/es/app.ftl, and locales/ja/app.ftl, unless the repository already has a convention.
  • Keep en-US complete. Other locales may be partial only if fallback behavior is intentional, visible in tests, and acceptable for the product.
  • For Spanish, avoid baking gender, number, or formality choices into code. Let translators choose variants and agreement in .ftl.
  • For Japanese, avoid assumptions about spaces, capitalization, or English plural categories. Let the message own sentence order and politeness level.
  • Test long strings, short strings, missing translations, bidirectional content, pseudolocalized text, and accessible names. Test a real RTL locale and mixed-direction content, not only a flipped layout. Include screen-reader text and ARIA attributes in localization review when they are user-visible.

Binding Guidance

Use local dependency versions and current upstream docs before changing APIs.

  • JavaScript/TypeScript: fluent.js packages include @fluent/bundle for core FluentBundle/FluentResource formatting, @fluent/syntax for parsing and tooling, @fluent/langneg for locale negotiation, @fluent/dom for DOM localization, and @fluent/react for React integration. Use javascript-typescript-engineering for package-manager, build, and type/test mechanics.
  • Python: python-fluent provides fluent.syntax for parsing, serialization, AST tooling, and analysis; fluent.runtime for FluentLocalization, FluentResourceLoader, format_value, and format_message; and fluent.pygments for syntax highlighting. Use python-engineering for packaging, typing, tests, and Python implementation structure.
  • PHP: discover the installed ext-intl version and project conventions before choosing MessageFormatter, NumberFormatter, IntlDateFormatter, locale PHP projects.
  • Rust: fluent-rs includes crates such as fluent, fluent-bundle, fluent-fallback, fluent-resmgr, fluent-syntax, fluent-pseudo, fluent-testing, and fluent-cli. Low-level bundles format messages for a locale or locale chain; higher-level fallback/resource-manager crates can own resource loading and fallback. Use rust-engineering and rust-testing-quality for Rust code and quality gates.
  • Swift/SwiftUI/macOS: prefer Apple's String Catalogs (.xcstrings), LocalizedStringKey/String(localized:), FormatStyle, and Locale; do not impose Fluent on Apple-platform projects unless the repository already uses it.

Testing and Validation

  • Keep catalog and runtime validation separate. In the catalog lane, parse and add each resource with the repository's pinned binding or parser, checking parse and add-resource errors such as syntax failures, duplicate IDs, or missing default variants.
  • In the runtime call-site lane, format through the pinned binding with representative arguments; cover selector branches, fallback, locale-specific number/date output, missing translations, unknown message, term, attribute, or function references, and missing-argument/error handling. Format every relevant message and attribute, or use a binding-specific semantic analyzer that proves equivalent reference coverage. Test message IDs and accessible labels at the call sites that render them.
  • Add regression tests near the code that formats messages; add E2E coverage when locale affects layout, navigation, ARIA names, forms, direction, or user-visible flows.
  • Use pseudolocalization or long-string fixtures to catch clipped text, concatenation assumptions, and layout coupling.

Security and Accessibility

  • Load security-review and security-review-evidence when localized content, locale tags, translation files, templates, Markdown/HTML, user-generated text, remote catalogs, or interpolation cross a trust boundary.
  • Do not assume Fluent sanitizes output for every sink. Escape or sanitize for the target context, and do not insert translated strings into innerHTML unless an official, reviewed overlay mechanism is used safely.
  • Treat translator-controlled markup and attributes as security-sensitive. In DOM/React integrations, prefer official Fluent overlay/component APIs and allow translated attributes only when the sink is safe and intentional.
  • Validate and normalize locale inputs before using them in file paths, URLs, cache keys, or database queries.
  • Localize visible labels, placeholders, titles, errors, and ARIA attributes together so screen-reader and keyboard users receive the same meaning as visual users.

References

Zod Error Localization

When Zod is selected, load zod-engineering. Translate stable issue codes plus bounded fields at render time; test precedence/fallback, avoid per-request global z.config() mutation, and never expose raw input.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.