Guide
Software internationalization: get the application ready for other languages.
Internationalization (i18n) is the work in the code that lets an application run in any language without further code changes. Localization (l10n) is the translation that follows. This checklist covers what a Windows desktop application needs, and how to find what is still missing before translation starts.
- Internationalization
- Once, in the code, by developers
- Localization
- Per language, in the resources, by translators
- Goal
- A new language needs no code change
- Check
- Run the application in a pseudo-language
On this page
Internationalization comes first, localization repeats.
Each problem left in the code shows up again in every language: a message that stays in English, a label cut off, a date in the wrong order. Fixed once in the code, it is fixed for all of them.
Internationalization (i18n)
- Text moves from the code into resources.
- The code handles any script and any text length.
- Dates, numbers, and sorting follow the user's locale.
- Done by developers, before the first translation.
Localization (l10n)
- Resources are translated and checked for each language.
- Dialogs are adjusted where a translation runs long.
- Changed text is translated again with each release.
- Done by translators and reviewers, for every release.
Globalization (g11n) is the umbrella term for both. Localizability is how well the application is prepared: an application with high localizability needs no developer when a language is added.
Checklist
Eight things to get right in the code.
1. All user-visible text is in resources
Text in the code stays in English in every language. Move it to the resources of your platform: string tables in .rc files, .resx files for .NET, resource strings for Delphi, .properties for Java. Text that the program uses as data, such as registry keys and file names, stays in the code or is locked against translation.
2. The application is Unicode
Build with Unicode (UNICODE and _UNICODE in C++, the default in .NET and Delphi 2009 and later). A non-Unicode application shows its text in the system code page: Japanese turns into question marks on a Western Windows.
3. Whole sentences, with placeholders
Word order differs between languages, so a sentence glued from pieces cannot be translated correctly. Keep the sentence in one resource and insert values through placeholders the translator can move. Numbered placeholders let the order change.
// Don't: three pieces the translator sees separately
msg = L"Deleted " + std::to_wstring(n) + L" files from " + folder;
// Do: one resource string, "Deleted %1!d! files from %2."
// In German: "%2: %1!d! Dateien gelöscht."
FormatMessageW(FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, ...);
// .NET: Resources.Deleted = "Deleted {0} files from {1}."
string.Format(Resources.Deleted, n, folder);
Plurals need care: English has two forms, other languages have one, three, or more. Either keep separate strings per form or phrase the text so that it works for any number.
4. Room for longer text
Short strings grow the most in translation. A label of up to ten characters can need two to three times its English length in a European language; long sentences grow by about a third. Leave space in dialogs and forms, or use layouts that grow with the text.
Figures: average length of translations from English into European languages, published by IBM and quoted by W3C in Text size in translation.
5. Dates, numbers, and currency follow the locale
Format with the user's locale instead of a fixed pattern: 3/4/2026 is March in the US and April in Germany, and the decimal point is a comma in much of Europe. Use GetDateFormatEx and GetNumberFormatEx in Win32, and the current culture in .NET (date.ToString("d")). Parse user input with the same locale, and store data in a fixed, culture-independent form.
6. Sorting and comparison are language-aware
Alphabetical order differs: German sorts ä with a, Swedish after z. Sort text shown to users with CompareStringEx or string.Compare with the current culture; compare identifiers with an ordinal comparison.
7. Fonts and scripts
Don't hard-code a font that lacks the characters of the target language. Use the system UI font where you can, and let the translated resources change the font where a language needs one, such as Japanese or Chinese.
8. Right-to-left languages
Arabic and Hebrew read from right to left, and the whole layout mirrors: the close button moves left, the order of columns reverses. Plan for mirrored dialogs and windows if these languages are on your list, and keep icons that show a direction separate so they can be flipped.
Test internationalization before translation.
Pseudo-localization replaces every string with a longer, accented imitation and lets you run the application in it. Text still in English is not in the resources; text cut off needs more room; broken characters mean the application or its fonts cannot show the language.
With Lingobit
What Lingobit checks, and what stays in your code.
Lingobit helps with
- Moving hard-coded strings into resources: Lingobit Extractor for C++, C#, Visual Basic .NET, Delphi, and Java.
- Locking strings the program uses as data.
- Pseudo Translate and Run Localized Application (Professional and higher).
- Validation of placeholders, cut-off text in dialogs, and hotkeys.
- A list of strings whose characters the file's code page cannot hold.
- Mirroring dialogs and forms for right-to-left languages with Flip.
Stays in your code
- Building the application for Unicode.
- Whole sentences with placeholders instead of glued pieces.
- Locale-aware formatting, parsing, and sorting.
- Loading the language at startup and switching it.
- Final testing in the real application.
Questions.
Why "i18n"?
Internationalization has 18 letters between the first i and the last n. Localization is l10n and globalization g11n the same way.
Can an application be localized without internationalization?
Partly. A compiled Windows application can be translated from its resources without source code, but text written in the code stays in English and glued sentences stay wrong. Pseudo-localization shows how much of the application that affects.
When should internationalization happen?
As early as possible: each string written straight into the code later has to be found and moved. For an existing application, start with an Extractor scan and a pseudo-localized build to see the size of the job.
Related paths
- Pseudo-localization — Test the application in an imitation language.
- Lingobit Extractor — Move hard-coded strings from source code into resources.
- Localization preparation — Extract, lock, test, and find before translation.
- Platform guides — Win32, .NET, WPF, Delphi, Java, Qt, and more.