Reference · the guide on one page
Reference sheet
Each chapter's takeaway, then the numbers the guide keeps citing. Prints on one sheet, A4 or Letter.
The 21 takeaways
Part 1 · Getting oriented
- 01Orientation. Four layers render every localized string: Unicode supplies the characters, CLDR the locale data, the ICU/Intl engine applies it, and a BCP 47 tag names the request. Route every locale bug to its layer.
Part 2 · Three visible failures
- 02Text expansion. Budget +200–300% width for short strings and design layouts that flex. If the German fits, most things fit.
- 03Formatters. Never hand-format numbers, dates, or money. Pass a locale and options to Intl.* and ship exactly what it returns, including the unexpected characters.
- 04Plurals & gender. Never branch on count === 1. Resolve a CLDR plural category, key strings by category, and let the runtime pick the arm.
Part 3 · The Intl toolbox
- 05Lists & ranges. Joining values into a sentence is grammar work: Intl.ListFormat carries each locale's connectives, formatRange decides how much of a range to repeat, and selectRange answers which plural form a range takes. None of it survives a hardcoded dash or comma.
- 06Sorting. Alphabetical order is locale data. Use Intl.Collator for anything a user reads as a sorted list. Code-point sort is wrong in most languages, sometimes in two ways in one language.
- 07Time zones. Store UTC instants plus an IANA zone name for anything human-scheduled. Offsets are political, they change, and some of them end in :30 and :45.
- 08Calendars. The year number, the era, and the shape of the week are all locale data. Store ISO 8601, format through the calendar the locale resolves, and never do arithmetic on a formatted year.
- 09Locale fallback. Locale negotiation is a chosen algorithm. Know whether the stack uses RFC 4647 lookup, best-fit matching, or Accept-Language parsing. The three give different answers from the same inputs.
Part 4 · Scripts and layout
- 10Line-breaking. CJK and Thai do not wrap at spaces: they wrap by prohibition rules and dictionaries. Test narrow widths with line-break: strict and real text, not lorem ipsum.
- 11CJK fallback. Declare lang and ship an explicit CJK font stack. Without them, the OS substitutes a default font: a different one per platform, with the wrong glyph variants.
- 12BiDi. Wrap every interpolated variable in FSI/PDI isolates. Characters with no direction of their own ($, digits, punctuation) take it from their neighbors. Never leave them to guess.
- 13RTL mirroring. The bidi algorithm mirrors text for free. Nothing mirrors the layout. Write CSS in logical properties (inline-start / inline-end) so dir="rtl" on the html element flips the whole UI. Then audit icons separately, because CSS moves boxes, not glyphs.
Part 5 · Strings, names, and input
- 14Unicode pitfalls. A string is not what it looks like. Normalize before comparing, segment by graphemes before counting or slicing, and pin the locale for case operations.
- 15Encoding. A string holds code points, a file holds bytes, and the encoding is the map between them. Mojibake is what happens when the reader uses a different map than the writer.
- 16Input parsing. Intl formats and never parses; the inverse falls to application code. Derive each locale's separators from formatToParts, fold digit blocks by code-point arithmetic, and keep the wire format (ISO 8601, plain numbers) locale-free.
- 17Address & name. Collect the fewest, loosest fields each country needs. Validation rules imported from the home market reject real customers at the moment they try to pay.
Part 6 · Shipping translations
- 18Translation pipeline. A translator can only work on what leaves the repo: one externalized message per sentence, with placeholders and a context note. Keep source wording consistent: repetition is the only discount the pipeline gives.
- 19Pseudoloc. Pseudolocalize in CI, before any money goes to translators. It finds hardcoded strings, concatenation, and brittle layouts while they are still cheap to fix.
- 20LQA scoring. A review round is only useful when it produces a number someone can act on: an error typology, a severity, a penalty, a threshold.
- 21The audit. Read the screen as its market reads it. Audit numbers, dates, plurals, direction, layout, names, and input against the locale's own conventions: a deviation from the locale's formatter is a bug, and a deviation from English is not.
Numbers the guide keeps citing
Cardinal plural categories
One translated arm per category, per counted message. Computed with Intl.PluralRules.
| Language | Arms | Categories |
|---|---|---|
| Chinese zh | 1 | other |
| Japanese ja | 1 | other |
| English en | 2 | one other |
| German de | 2 | one other |
| Turkish tr | 2 | one other |
| French fr | 3 | one many other |
| Hebrew he | 3 | one two other |
| Portuguese pt | 3 | one many other |
| Romanian ro | 3 | one few other |
| Spanish es | 3 | one many other |
| Czech cs | 4 | one few many other |
| Polish pl | 4 | one few many other |
| Russian ru | 4 | one few many other |
| Arabic ar | 6 | zero one two few many other |
| Welsh cy | 6 | zero one two few many other |
MQM severity weights
The defaults from MQM's worked examples. Real scorecards configure them. Penalties norm per 1,000 words, so the raw pass threshold sits near 99, not 90. A critical count above zero fails the delivery regardless of score.
| Severity | Weight | Applies when |
|---|---|---|
| Neutral | ×0 | Noted for the record, but it costs the reader nothing. Often a preference. |
| Minor | ×1 | Noticeable, but the meaning survives. The reader is slowed, not stopped. |
| Major | ×5 | The reader is misled, confused, or blocked on this string. |
| Critical | ×25 | Safety, legal, financial, or brand damage. The kind that stops a release. |
Text expansion rule of thumb
Short English source strings swell most. For up to 10 characters, plan for 200–300% growth (IBM's guidance, republished by W3C). Buttons, tabs, and badges are where fixed widths break first.
Locale tag anatomy (BCP 47)
sr - Cyrl - RS - u - ca-buddhist │ │ │ └── extension: calendar override │ │ └── region subtag (ISO 3166-1) │ └── script subtag (ISO 15924) └── language subtag (ISO 639)
Script and region are optional. The -u- extension carries calendar, numbering system, and collation overrides.