What is i18n?

i18n is short for internationalization, with 18 standing for the letters between the i and the n: it means building an app or website so it can be localized easily for other languages and regions. Translinga explains the basics below, from string files to the 6 plural categories in Unicode CLDR.

All guidesUpdated

Where strings live, by platform

PlatformString filesPlurals
Androidres/values/strings.xml, plus res/values-xx/ per language<plurals> with zero, one, two, few, many, other
Apple (Xcode)Localizable.xcstrings string catalogVary by Plural
Web (i18next, next-intl, vue-i18n)JSON locale filesDepends on the library
Any platformICU MessageFormat messagesPlural and select arguments
Translinga CLIReads i18next, next-intl, vue-i18n and any JSONKeeps placeholders intact

What i18n means

i18n is short for internationalization: there are 18 letters between the "i" and the "n." W3C defines it as designing and developing content so it can be easily localized for audiences that vary in culture, region or language.

For your app or website, that includes enabling Unicode, keeping localizable content separate from source code, and supporting local formats for dates, times, numbers and names. You also need to be able to load localized versions for each user.

Where do you start? With the code and content you already have. Look at where your interface text lives, where you format values, and how you'll load a user's language.

Not just the words.

Move strings out of the code

Keep text that needs translation in locale files rather than directly in your interface code. W3C also says your code shouldn't depend on the values of interface strings. Use keys to refer to messages, rather than making the displayed wording part of your code's logic.

That separation is part of i18n: your source code refers to a message, and the localized content can be loaded for the user without putting each translated version into the source code itself.

Give those messages some context, too. In Translinga, you can add a $context note to a JSON file to describe what the strings are for, and the key names count as context as well.

You don't have to put that explanation into the text your user sees.

Plurals and variables

Don't treat every plural message as a choice between singular and plural. Unicode CLDR defines six plural categories: zero, one, two, few, many and other.

Check your message format.

ICU MessageFormat supports plural arguments and select arguments, and it treats a message as a single unit for translation. When a message contains a variable or needs a plural form, keep the message together rather than assembling it from separately translated fragments.

What should you look for in your setup? Support for those arguments, with the surrounding message included for translation. You're working with a whole message, even when part of it changes according to a value. Keep that in mind when you move text out of your code.

Dates, numbers and currency

Moving strings is part of the work, but W3C's definition also covers support for local formats for dates, times, numbers and names. Review those wherever they appear in your app or website, not just in your locale files.

For currency, look at number formatting too. Don't leave the formatting decision buried in the displayed text while treating the rest of the interface as localizable.

And keep names in the review. They're part of the local-format support W3C includes in i18n, alongside dates and numbers (not just another piece of interface copy).

Your review needs to cover both the translated messages and the values you show with them.

i18n on Android, iOS and the web

On Android, strings live in res/values/strings.xml, with translations in folders such as res/values-pl/. Android also has a <plurals> resource.

Per-app language settings arrived in Android 13. Google's docs point out that adding those settings doesn't translate your app's resources by itself, so keep the language setting and the translated resources as separate items in your work.

For Apple apps, Xcode uses string catalogs, with Localizable.xcstrings as the catalog file. You'll find Vary by Plural and Vary by Device options there.

On the web, Translinga's CLI reads locale files from i18next, next-intl and vue-i18n, or any JSON. Its CLI and GitHub Action can sync those files on every push with npx translinga sync --to nl,de,fr, translating only new and changed strings.

Common mistakes

Watch for code that relies on the exact wording of an interface string. W3C explicitly includes avoiding that dependency in its i18n guidance.

Then check the messages themselves: text still sitting in source code, plural messages reduced to singular and plural, or messages split into fragments instead of kept together for translation. Those are separate checks, not something a language selector takes care of.

Have you covered formats as well as text? Go back through dates, times, numbers and names before calling the work done.

On Android, don't mistake the presence of per-app language settings for translated resources. You still need the translations in the app's resources.

FAQ

Questions, answered

Is i18n the same as translation?

No. i18n is the design and development work that makes content easy to localize, including separating localizable content from source code and supporting local formats. Translation is part of the localized content you load for a user.

Why is internationalization shortened to i18n?

There are 18 letters between the first "i" and the last "n" in internationalization. The abbreviation keeps those letters at either end and replaces the letters between them with their count.

Do I only need singular and plural messages?

Unicode CLDR defines six plural categories: zero, one, two, few, many and other. Use message support that can represent those categories rather than limiting your setup to singular and plural.

Does Android's per-app language setting translate my app?

No. Per-app language settings arrived in Android 13, but Google's docs say adding them doesn't translate your resources. You still need to provide the translated resources.

Start free

Try it on your messiest theme file

Your first $1 is free, about 400k characters on Fast. No card needed for a key.

Printed proof sheets marked up in blue pencil, with one word struck through in red, on a dark navy desk