Localization Rules
Rules for building genuinely localizable products: externalized strings, no string concatenation, ICU pluralization, locale-aware date/number/currency formatting, text expansion room, RTL awareness, meaning-first translation, and translator context.
0 downloads · Used by 0 stacks
Localization that's bolted on after launch is always more expensive and always more broken than localization designed in from the start — because most localization bugs come from architectural decisions (concatenated strings, hardcoded formats) made long before any translator ever sees the product. Treat every user-facing string as a variable, never a literal, from the first line of code.
Externalize every string
- Never hardcode user-facing copy directly in application code — every string a user can see goes through a translation/resource system from day one, even in a product that currently ships in only one language. Retrofitting externalization after strings are scattered through the codebase is far more expensive than doing it from the start.
- Externalize strings that seem like edge cases too: error messages, empty states, button labels inside modals, alt text, email subject lines, push notification text — anything visible to a user needs a translation key, not just primary UI copy.
No string concatenation
- Never build sentences by concatenating translated fragments around a variable (
"Hello, " + name + "!") — word order, grammatical gender agreement, and sentence structure vary by language in ways that concatenation can't accommodate, and it produces broken grammar in most target languages even when it reads fine in the source language. - Use full parameterized message templates instead (
"Hello, {name}!"as one translatable unit) so a translator can reorder or restructure the whole sentence for their language's grammar, not just fill in a slot at a fixed position.
Pluralization via ICU rules
- Use a proper pluralization system (ICU MessageFormat or equivalent) rather than a naive
count === 1 ? singular : pluralcheck — many languages have more plural categories than English's two (some have none, some have several), and a binary check silently produces wrong grammar for those languages. - Never assume "just add a number" is sufficient ("5 files") without confirming the surrounding sentence structure is also correct in the target language's plural form — the plural category can change more than just a suffix.
Date, number, and currency formatting per locale
- Format dates, numbers, and currency through the runtime's locale-aware formatting APIs (e.g.
Intlin JavaScript) keyed to the user's actual locale, never hardcoded to one format (MM/DD/YYYYis not universal, and neither is a.for a decimal separator). - Store dates and currency amounts in an unambiguous, locale-independent form (ISO 8601, a numeric amount plus a currency code) and only format for display at render time in the viewer's locale — formatting at storage time bakes in an assumption about the wrong locale for someone else reading it later.
Text expansion space
- Design UI layouts to tolerate significant text expansion in translation — German commonly runs 30-35% longer than English for the same meaning, and some languages run even longer; a layout that only fits the English string breaks visibly once translated.
- Test layouts against a deliberately long placeholder string (or actual German/Finnish copy) during development, not only against the source-language string — a truncated or overflowing button label found in QA is far cheaper to fix than one found after a translated release ships.
RTL awareness
- Build layouts using logical properties (start/end) instead of physical ones (left/right) wherever the framework supports it, so the layout mirrors correctly for right-to-left languages (Arabic, Hebrew) without a separate manual RTL layout.
- Test the actual RTL rendering, not just the string content — icons implying directionality (arrows, back buttons), text alignment, and reading order all need to flip, and a text-only RTL check misses layout-level breakage.
Translate meaning, not words
- Give translators the intended meaning and tone, not just the literal source string, especially for idioms, humor, and culturally-specific references — a literal word-for-word translation of an idiom is frequently nonsensical or unintentionally funny in the target language.
- Allow (and expect) translators to restructure a sentence entirely to preserve meaning and tone rather than mapping word-for-word — a translation graded on how closely it mirrors source sentence structure produces worse results than one graded on whether it reads naturally and means the same thing.
Screenshots for translator context
- Provide translators with screenshots or a live preview of where each string appears in the UI, not just an isolated spreadsheet of source strings — the same source word can require different target words depending on whether it's a button, a heading, or a menu item, and translators guessing at context produce systematically worse translations.
- Flag character-length-constrained strings (button labels, tab names) explicitly with their space constraint when handing them to translators — a translator working blind has no way to know a string needs to fit in a 12-character button.
Badge
Link back to this module from your own README.
[](https://markdowners.com/m/markdowners/localization-rules)Discussions about this module
No discussions about this module yet.
Start a discussion
Comments (0)
Sign in to comment. Sign in
No comments yet. Be the first to add one.