i18n: Основное руководство по интернационализации программного обеспечения

What internationalization (i18n) means, how it differs from localization, and the seven engineering practices that let you add a language without rewriting code: UTF-8, externalised strings, ICU plurals, Intl formatting, flexible layouts, locale URLs and pseudo-localization.
Нет данных карты Никаких обязательств

· Обновлено · Алекс Б · Блог

Подведите итог этому посту следующим образом: 9 мин чтения

Internationalization (i18n) is the work you do in code so that a product can be adapted to any language or region without being re-engineered. The W3C defines it as “the design and development of a product, application or document content that enables easy localization for target audiences that vary in culture, region, or language” (W3C). In practice that means Unicode everywhere, no hard-coded user-facing strings, locale-aware formatting of dates, numbers and plurals, and layouts that survive longer text and right-to-left scripts.

Ключевые выводы

  • i18n is engineering; localization (l10n) is the adaptation for one market that i18n makes possible. The “18” and “10” count the letters between the first and last letter of each word.
  • The five habits that prevent most i18n bugs: UTF-8 end to end, externalised strings, ICU-style plural and variable handling, the platform’s locale formatting APIs, and flexible layouts.
  • Never build sentences by concatenating fragments. Word order and plural rules differ too much between languages.
  • Test with pseudo-localization before a translator ever sees the strings.
  • A website that is already live and was not built for i18n can still be made multilingual at the rendering layer, without refactoring the codebase.

i18n, l10n and g11n: the difference

TermStands forЧто это значит
i18ninternationalizationBuilding the product so it can support any locale
l10nлокализацияAdapting it for one locale: translation, formats, imagery, legal text
g11nглобализацияThe business process that combines both to enter new markets

The W3C lists what internationalization typically includes: removing barriers to localization (Unicode and character encoding), supporting features like bidirectional text, supporting local conventions for dates, calendars, numbers and names, and “separating localizable elements from source code” so the right version loads for each user (W3C).

Here is a simple test of whether the i18n work is done: adding a new language should need translators and some configuration. If it needs a developer, something was missed.

1. Use Unicode (UTF-8) end to end

UTF-8 is the default for the web, used by 99.1% of websites whose character encoding is known (W3Techs, 28 сентября 2026 г). These days the mistakes are rarely in the HTML. They happen in the layers around it:

  • Database columns and connections that are not set to full UTF-8. In MySQL, utf8 is a 3-byte subset; use utf8mb4 or emoji and some CJK characters will be lost.
  • String functions that count bytes instead of characters, which truncate “Zürich” or “東京” in the middle of a character.
  • CSV exports opened in spreadsheet software with the wrong encoding.
  • Sorting with byte order instead of locale collation, which puts “Äpfel” after “Zebra”.

Declare the encoding once (<meta charset="utf-8">), set it on every connection, and use locale-aware comparison such as Intl.Collator in JavaScript.

2. Externalise every user-facing string

Strings that users see belong in resource files, keyed by an identifier. Keep them out of templates and code:

{
  "cart.title": "Your cart",
  "cart.empty": "Your cart is empty",
  "cart.checkout": "Go to checkout"
}

Each locale gets its own file, and the code asks for cart.title. Frameworks follow the same pattern: in Vue, the vue-i18n library exposes $t for “locale message translation” and $i18n for the global instance that manages locales and messages (vue-i18n docs). React (react-intl, i18next), Angular (@angular/localize), Django, Rails and Laravel all ship an equivalent.

A few rules that save pain later:

  • Give translators context. “Open” can be a verb (open the file) or an adjective (the store is open). Add a description to each key.
  • Don’t reuse a key just because the English text matches. “Save” on a button and “Save 20%” in a banner are different messages in most languages.
  • Keep markup out of strings where you can, or use placeholders for it, so translators can’t break your HTML.

3. Never concatenate sentences; use placeholders and plural rules

This looks harmless:

'You have ' + count + ' new messages';

It breaks in two ways. Word order changes between languages, and plural rules are not “1 vs. everything else”. The Unicode CLDR plural rules give English two cardinal categories (one, other), Japanese one, Russian and Polish four (one, few, many, other) and Arabic six (zero, one, two, few, many, other) (Юникод CLDR).

Use a message format that knows those rules, such as ICU MessageFormat:

{count, plural,
  =0 {You have no new messages}
  one {You have # new message}
  other {You have # new messages}}

A Russian translator can then add the few и many forms without any change to your code. The same applies to gender, ordinal numbers (“1st, 2nd”) and lists (“A, B and C”).

4. Let the platform format dates, numbers and currency

03/04/2026 is 4 March in the United States and 3 April in most of Europe. 1,234.5 in English is written 1.234,5 in German and 1 234,5 in French. Don’t write your own formatting. Every modern platform has locale data built in, and in JavaScript it is the Intl API (МДН):

new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(1234.5);
// "1.234,50 €"

new Intl.DateTimeFormat('fr-FR', { dateStyle: 'long' }).format(new Date('2026-09-27'));
// "27 septembre 2026"

Some related decisions are worth making early:

  • Store time in UTC and convert it to the user’s time zone for display.
  • Keep currency separate from locale. A French-speaking visitor in Canada pays in CAD, not EUR. Formatting a number as a currency is i18n; deciding the price is a business decision.
  • Don’t assume how names and addresses are shaped. Many people don’t have a “first name” and “last name” in the Western sense, and postal codes are not always numeric.

5. Design layouts that stretch and flip

Translated text is often longer than English, and short strings grow the most. The W3C summarises IBM’s guideline figures: strings of up to 10 characters can grow by 200 to 300% in European languages, while text over 70 characters grows to about 130% (W3C, Text size in translation). Their example is Italian turning “views” into “visualizzazioni”.

For UI work, that means:

  • No fixed-width buttons or tabs sized for English labels.
  • No text baked into images. It can’t be translated without redrawing the image.
  • Support right-to-left scripts (Arabic, Hebrew, Persian, Urdu) with dir="rtl" на <html> element and CSS logical properties (margin-inline-start вместо margin-left), so the layout mirrors itself.
  • Pick fonts that cover the scripts you plan to support, or define fallbacks.

6. Handle locale detection and URLs deliberately

Decide how a user’s locale is chosen and how it is remembered:

  1. An explicit choice (a language switcher) always wins.
  2. Otherwise, use the browser’s Accept-Language header as a suggestion, not a forced redirect.
  3. Put the locale in the URL (/de/, de.example.com) for any public page, so each language version can be shared, cached and indexed by search engines. Cookies alone make translated pages invisible to Google.

If the product has public pages, those language URLs also need hreflang annotations; see the руководство по хрефлангу.

7. Test with pseudo-localization

Pseudo-localization replaces your source strings with an altered version before any real translation exists, for example [Ýöûŕ çåŕţ îš éɱþţý !!!!]. The accents catch encoding problems, the padding catches layouts that break under longer text, and the brackets reveal truncation and any hard-coded string that didn’t change. Many i18n libraries and build tools can generate a pseudo-locale; run your UI test suite against it on every release.

Add these to your checklist too:

  • Switch to an RTL locale and check navigation, icons with direction (arrows, progress bars) and form alignment.
  • Test sorting and search with accented characters.
  • Check emails, PDFs, error messages and push notifications, which are often forgotten.

An i18n checklist for new projects

  • UTF-8 (utf8mb4 in MySQL) in files, database, connections and APIs
  • All user-facing strings in resource files, with context for translators
  • ICU MessageFormat (or equivalent) for plurals, gender and variables
  • Intl or the platform’s locale APIs for dates, numbers, currency, lists and sorting
  • UTC storage and per-user time zone display
  • Flexible layouts, CSS logical properties, dir attribute support
  • Locale in the URL for public pages, hreflang for search engines
  • Pseudo-localization in CI

When the website already exists

Everything above applies to an application you are building. For a marketing site, a store or a CMS that is already live, it means a large refactor, and the team that owns the content is usually not the team that owns the code.

For that case, translation can happen at the rendering layer instead. ConveyThis reads the text your site already outputs, translates it into any of 210 languages, and serves each language on its own URL (subfolder or subdomain on the Business plan and higher, or a ?lang parameter) with hreflang added automatically. Right-to-left languages get the text direction switched, images can be replaced per language, and a glossary and translation memory keep product names and terms consistent. It installs as a Плагин WordPress, a Shopify app or a single script on any other stack, so the i18n work in your codebase can continue on its own schedule. For the business side of adapting content to each market, read our guide on what content localization involves.

Часто задаваемые вопросы

Why is internationalization abbreviated i18n? There are 18 letters between the first “i” and the last “n” in “internationalization”. Localization (l10n) follows the same pattern.

Is i18n the same as translation? No. Translation is one part of localization. i18n is the engineering that lets translation, and every other local adaptation, happen without code changes.

When should a project start i18n? At the start. Externalising strings and using locale APIs costs little on day one and a lot when retrofitted into a mature codebase.

What is $i18n in Vue? In vue-i18n, $i18n is the global instance that manages locales and messages, and $t is the function that returns a translated message for a key (vue-i18n).

Следующий шаг

If you need a live website in several languages before the codebase is fully internationalised, создать учетную запись ConveyThis and publish your first language, then compare планы when you add more.

Поделиться:
G2 High Performer Spring 2023
G2 Easiest Setup Fall 2024
G2 Best Support Spring 2025