The course
21 short lessons on how software breaks in other languages.
6 units, roughly 170 minutes if you work straight through. Every lesson pairs a live demo with the machinery under it, a note from a real incident, and a three-question check. Progress stays in your browser.
New here? Take the units in order. They start with failures you can see on screen. Chasing a specific bug? Jump straight to its lesson. The course ends with a final audit: a checkout screen shipped broken in three markets, with twelve planted bugs to find.
The course at a glance
Every lesson, unit by unit. The marked node is the first check you have not passed. Start there, or go to the lesson your bug report is about.
Unit 1 · Getting oriented
0/1 passed
Unit 2 · Three failures you can see
0/3 passed
Unit 3 · The Intl toolbox
0/5 passed
Unit 4 · Scripts and layout
0/4 passed
Unit 5 · Strings, names, and input
0/4 passed
Unit 6 · Shipping translations
0/4 passed
Unit 1
Getting oriented · What localization work is made of
Four terms (i18n, l10n, g11n, t9n) and four layers of machinery (Unicode, CLDR, ICU, BCP 47) cover most of this course. One lesson puts them in place before the other lessons use them.
Unit 2
Three failures you can see · Layout swell, formatting, plural grammar
The three most common ways a shipped product breaks in another language. Each failure appears in seconds. These lessons also teach the habit the rest of the course depends on: the locale decides, not your code.
- 02Text expansionTranslation length variance & layout flexLv 101~6 minResize a button against real German, Russian, and Finnish strings until it breaks. The demo measures the swell in pixels and characters.
- 03FormattersIntl.* APIs and CLDR dataLv 101~8 min$1,234.56 / 1.234,56 € / ¥1,235 / ١٬٢٣٤٫٥٦: one number, 24 locales. Skeleton-style controls included.
- 04Plurals & genderNumeric agreement & gender selectionLv 101~10 minDrag a count and watch each language render its own plural forms (яблоко / яблока / яблок). Then trace how an i18n runtime resolves the string. Ordinals and gender are included.
Unit 3
The Intl toolbox · The APIs that already know the answer
The browser ships locale data for lists, ranges, sorting, time zones, and calendars. Most i18n bugs come from code that does not ask it. This unit covers the API surface and the negotiation step that decides which locale you are in.
- 05Lists & rangesList, range & duration formattingLv 101~6 min'A, B und C', 'Jan 3 – 5', '2–4 items', '1 hr 20 min': the joining and range side of the Intl API surface. The connective word and the collapsed date are both locale data.
- 06SortingLocale-aware sorting and comparisonLv 201~6 minPolish ł sorts between l and m. Swedish ä sorts after z. German has two competing orderings (dictionary vs phonebook). Icelandic sorts the phone book by first name. Watch the same list reshuffle across six locales.
- 07Time zonesTime zones & calendar edge casesLv 201~8 minHalf-hour offsets, leap seconds, the day Samoa skipped Dec 30, and why Australia/Lord_Howe shifts the clock 30 minutes for DST.
- 08CalendarsCalendar systems & week conventionsLv 201~8 minJuly 29, 2026 is also 15 Safar 1448, 15 Av 5786, and Reiwa 8. Eight calendars over one date, both modern Japanese era changes frame by frame, and the locale data that says whose weekend is Friday.
- 09Locale fallbackLocale matching & fallback chainsLv 201~8 minYour bundle has pt-PT. A user arrives from São Paulo. Which language do they get, and which of three negotiation algorithms decided?
Unit 4
Scripts and layout · Writing systems meet CSS
Text that wraps by dictionary, fonts negotiated per character, right-to-left scripts, and layouts that must mirror. None of these bugs appear in an English-only build. You must load the locale to see them.
- 10Line-breakingWrapping rules & word segmentationLv 201~7 minWhy CSS `line-break: strict` matters for CJK and Thai, and what happens at narrow widths in 9 locales.
- 11CJK fallbackFont stacks & glyph coverageLv 201~7 minInspect the font your browser used to render each glyph. See why a 'pure sans-serif' headline silently switches to the OS default for one Hanzi, with a different default on each platform.
- 12BiDiUnicode bidi algorithm & directional isolatesLv 301~10 minEmbed numbers, English brand names, code, and timestamps inside an Arabic sentence. Watch what Unicode isolates fix and what they do not.
- 13RTL mirroringLayout mirroring & CSS logical propertiesLv 201~8 minThe same app frame built twice (physical CSS against logical CSS), toggled between English and Arabic. Chevrons, progress bars, and paddings mirror in one column and break in the other.
Unit 5
Strings, names, and input · Data that comes from people
A string's .length lies. Names do not fit a first/last schema, and your parser fails on 1.234,56. This unit covers the identity and input side of internationalization.
- 14Unicode pitfallsStrings, bytes, and what users seeLv 301~8 minTurkish toLowerCase('ID') is 'ıd', not 'id' (this is how Spring CVE-2024-38820 happens). 'café' === 'café' returns false. 'family emoji'.length === 11.
- 15EncodingBytes, encodings, and charset mismatchLv 201~7 minThe same text as UTF-8 bytes vs UTF-16 code units. Then a live mojibake reproduction: café saved as UTF-8 and misread as Windows-1252 becomes café, computed in your browser.
- 16Input parsingLocale-aware input handlingLv 201~7 minNumber('1.234,56') is NaN. A German user typing a price, an Egyptian user typing ١٢٣٤, and a parser that asks the locale for its separators before it reads a digit.
- 17Address & namePersonal data & form fieldsLv 301~8 minPatrick McKenzie's 40 falsehoods, applied to a real form. UK postcode vs JP 〒, Spanish two surnames, Hungarian surname-first, why your CRM is wrong.
Unit 6
Shipping translations · The pipeline, the QA step, the final exercise
How strings travel: externalization, translation files, translation memory, the pseudolocalization pass that finds bugs before translators start, and the review round that scores the returned work. The course ends with an audit exercise over everything covered.
- 18Translation pipelineExternalization, file formats & TMLv 101~9 minExternalize a hardcoded string. Read the same message as gettext PO, XLIFF 2.0, and ICU JSON. Then watch a translation memory price repetition with fuzzy matches.
- 19PseudolocPre-translation QALv 101~6 minPaste any string. Get accented / expanded / RTL-flipped variants. CI pipelines run the same wire-protocol-friendly transforms.
- 20LQA scoringHow to measure translation qualityLv 201~12 minReview ten German checkout segments. Classify each error by MQM dimension and severity. Then watch the official penalty arithmetic decide whether the delivery passes. Clean segments are included, because over-flagging also costs.
- 21Capstone auditFind the failures you studiedLv 301~15 minA team that skipped this course shipped this checkout screen in three markets. Twelve of the failures you studied are in it. Find them, then check your audit against the answer key.
Evidence for planning meetings
Three lessons double as meeting evidence. Each runs in under a minute with no setup, and each answers a question that budget meetings ask.
Will this layout survive German?
Resize a button against real translations and watch where it breaks: the case for flexible layouts, in pixels.
Why does “n items” need six Arabic variants?
Every counted message needs one translated arm per plural category: six in Arabic, four in Russian. This lesson explains that line item.
Are we ready to translate at all?
Pseudolocalization finds hardcoded strings and brittle layouts before you pay for a single translated word.