All lessons

Reference · the course on one page

Reference sheet

Every lesson's one-line takeaway, unit by unit, followed by the numbers the course keeps citing. The tables import from the modules that own them, or Intl computes them at render time, so this sheet cannot drift from the lessons. Print it: the layout fits one-sided A4/Letter.

If you remember 21 things

Unit 1 · Getting oriented

  1. 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.

Unit 2 · Three failures you can see

  1. 02Text expansion. Budget +200–300% width for short strings and design layouts that flex. If the German fits, most things fit.
  2. 03Formatters. Never hand-format numbers, dates, or money. Pass a locale and options to Intl.* and ship exactly what it returns, including the characters you did not expect.
  3. 04Plurals & gender. Never branch on count === 1. Resolve a CLDR plural category, key your strings by category, and let the runtime pick the arm.

Unit 3 · The Intl toolbox

  1. 05Lists & ranges. Joining is grammar. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 09Locale fallback. Locale negotiation is an algorithm you choose. Know whether you use RFC 4647 lookup, best-fit matching, or Accept-Language parsing. The three give different answers from the same inputs.

Unit 4 · Scripts and layout

  1. 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.
  2. 11CJK fallback. Declare lang and ship an explicit CJK font stack. When you do not, the OS silently substitutes a default font: a different one per platform, with the wrong glyph variants.
  3. 12BiDi. Wrap every interpolated variable in FSI/PDI isolates. Neutral characters ($, digits, punctuation) take direction from their neighbors. Never leave them to guess.
  4. 13RTL mirroring. The bidi algorithm mirrors your text for free. Nothing mirrors your 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.

Unit 5 · Strings, names, and input

  1. 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.
  2. 15Encoding. A string is code points. A file is bytes. The encoding is the map between them, and mojibake is what you get when the reader uses a different map than the writer.
  3. 16Input parsing. Intl formats and never parses. The inverse is yours. 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.
  4. 17Address & name. Collect the fewest, loosest fields each country needs. Validation rules imported from your home market reject real customers at the moment they try to pay you.

Unit 6 · Shipping translations

  1. 18Translation pipeline. A translator can only work on what leaves your repo: one externalized message per sentence, with placeholders and a context note. Keep source wording consistent: repetition is the only discount the pipeline gives you.
  2. 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.
  3. 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.
  4. 21Capstone audit. Read the screen as its market reads it. Audit numbers, dates, plurals, direction, layout, names, and input against the locale's own conventions. Deviations from the locale's formatter are bugs. Deviations from English are not.

Numbers the course keeps citing

Cardinal plural categories

One translated arm per category, per counted message. Intl.PluralRules computes this table at render time.

LanguageArmsCategories
Chinese zh1other
Japanese ja1other
English en2one other
German de2one other
Turkish tr2one other
French fr3one many other
Hebrew he3one two other
Portuguese pt3one many other
Romanian ro3one few other
Spanish es3one many other
Czech cs4one few many other
Polish pl4one few many other
Russian ru4one few many other
Arabic ar6zero one two few many other
Welsh cy6zero 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.

SeverityWeightApplies when
Neutral×0Noted for the record, but it costs the reader nothing. Often a preference.
Minor×1Noticeable but the meaning survives. The reader is mildly slowed or mildly annoyed.
Major×5The reader is misled, confused, or blocked on this string.
Critical×25Safety, 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 source characters, plan for 200–300% growth (IBM's guidance, republished by W3C). Buttons, tabs, and badges are where fixed widths break first. If the German fits, most languages fit.

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.