Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Internationalization

Pattern

A reusable solution you can apply to your work.

Also known as: i18n

Understand This First

  • UX – internationalization is part of building a user experience that works for everyone.

Context

This is a tactical pattern that prepares software to work across languages, scripts, and regions. If your Application will ever serve users who speak different languages or live in different countries, internationalization is the architectural groundwork that makes that possible. It doesn’t translate anything itself; that’s Localization. Instead, it ensures the system is capable of being localized.

The abbreviation “i18n” comes from the 18 letters between the “i” and “n” in “internationalization.” You will see this abbreviation constantly in codebases, libraries, and documentation.

In agentic coding, internationalization is easy to overlook. An AI agent generating code in English will produce English-only strings, date formats, and number formats by default. Without explicit direction, you’ll end up with hardcoded text scattered throughout your codebase, a problem that becomes expensive to fix later.

Problem

You build a working application and then discover it needs to support Spanish, Japanese, and Arabic. String literals are embedded in UI components. Dates are formatted with month/day/year. Currency symbols are hardcoded. The layout assumes left-to-right text. Every one of these decisions now has to be found and reworked. How do you build software so that adapting to a new language or region doesn’t require rewriting the interface?

Forces

  • You might not need multiple languages today, but the cost of adding i18n later is much higher than building it in from the start.
  • Extracting all user-visible strings adds development overhead that feels unnecessary when you only support one language.
  • Different languages have radically different characteristics: German words are long, Chinese has no spaces, Arabic reads right-to-left, Japanese uses multiple scripts simultaneously.
  • Date, time, number, and currency formats vary by region, not just by language.

Solution

Separate all user-visible text and locale-dependent formatting from your application logic. This is the core principle: the code shouldn’t contain any strings that a user will see. Instead, it references keys that map to translated text stored externally.

Use a standard i18n library for your platform (such as gettext, react-intl, i18next, NSLocalizedString, or fluent). These libraries handle string lookup, pluralization, interpolation, and formatting. Don’t build your own.

Beyond strings, design for variability: layouts that accommodate longer or shorter text, right-to-left text direction, different date and number formats, and different sorting rules. Use Unicode (UTF-8) everywhere: source files, databases, APIs, and display.

When working with an AI agent, include internationalization requirements early: “Use the i18n library for all user-facing strings. No hardcoded text in components. Support RTL layouts.” This prevents the agent from generating code you will have to rewrite.

How It Plays Out

A team builds a SaaS product in English. Six months later, they land a French-speaking client. Every button label, error message, help text, and notification is a hardcoded string in JSX components. The i18n retrofit takes three developers two weeks, touching over 200 files.

Contrast this with a team that uses react-intl from day one. Each component references message IDs instead of literal text. Adding French support means creating a French message file and hiring a translator. The code doesn’t change at all.

A developer asks an agent to add form validation messages. The agent produces: "Please enter a valid email address." The developer redirects: “Use the i18n message key validation.email.invalid and add the English string to the messages file.” Now the validation works in any language the system supports.

Tip

Even if you only support one language, using i18n from the start has a side benefit: all user-facing text lives in one place, making it easy to review for consistency, tone, and completeness.

Example Prompt

“Replace all hardcoded UI strings with i18n message keys. Create an English messages file with the original strings. Use the format validation.email.invalid for validation messages.”

Consequences

Internationalized software can expand to new markets without rewriting its interface. The separation of text from code also improves maintainability. Changing a label or fixing a typo means editing a message file, not hunting through source code.

The cost is upfront discipline. Every user-facing string must go through the i18n system, which adds a small friction to development. Pluralization rules, gender agreement, and right-to-left layout support can be genuinely complex. And internationalization without actual Localization delivers no user value; it’s purely an enabling investment.

  • Enables: Localization — internationalization is the foundation that makes localization possible.
  • Depends on: UX — internationalization is part of building a user experience that works for everyone.
  • Supported by: Accessibility — many accessibility practices (semantic markup, content separation) also support internationalization.
  • Uses: Configuration — locale settings are a form of configuration.