Skip to content
Locale Lab

Chapter 21·Shipping translations·~15 min

The audit: a checkout shipped in three markets

One checkout screen, shipped to Germany, Egypt, and Japan without an i18n review. Twelve of the failures this guide covers are on it. The reader flags each defect, then checks the result against the answer key.

QAauditall parts

The problem

Each chapter isolates one failure. A real release ships them together: the number format bug sits two lines above the plural bug, and both hide behind a layout that only breaks in German. The skill is to find the failures on a screen nobody annotated, in a market whose conventions are unfamiliar. A localization review is that pass, and the team behind this checkout skipped it.

How it works

How to audit a screen

Every earlier chapter isolates one failure. A shipped screen composes them: the currency bug sits two lines above the plural bug, and the layout only clips in German. The auditor's trap is reading such a screen in home conventions. Read that way, a correct German price like 79,98 € looks like a typo while a wrong one like $1,298.98 reads fine. So the first rule is to switch reference frames: for every value on screen, establish what the market's own formatter would produce. Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }) renders that total as 1.298,98 €: point for grouping, comma for decimals, symbol after the number. That output is the yardstick for every flag the audit raises.

The second rule is to walk a fixed list instead of trusting the eye, because composed bugs mask each other. Numbers come first: separators, symbol side, digit script, minor units (the yen has none, so ¥12,800 is complete). Dates are next, and the question is whether 07/17 means the 17th of July or nonsense; a de-DE reader expects day first (17.7.2026 from Intl.DateTimeFormat('de-DE')). After that come plurals and leftover English, where an untranslated "item(s)" or a half-English sentence means a string never reached a translator, usually because code concatenated it. Direction gets its own pass: find where reading starts, which way arrows point, and whether every interpolated LTR value got bidi isolation. Layout (check for clipping), names (which name comes first in this market), and input (whether the postal-code field can hold a valid local code) close the walk. The list never asks whether anything looks odd: unfamiliar and wrong are different properties.

1 numbers    separators · symbol side · digit script · minor units
2 dates      field order · separators · calendar
3 plurals    leftover "(s)" · untranslated fragments
4 direction  reading start · arrows · bidi isolation
5 layout     clipping · truncation · fixed widths
6 names      field order · missing phonetic fields
7 input      postal formats · maxLength · placeholders
The audit checklist, one line per pass over the screen.

The demo

Try these, in order

Each step reproduces one specific failure in the demo below.

  1. 1
    On the "de-DE · Germany" tab, read the Gesamt line the way a German shopper would, checking which character groups thousands and which marks decimals. Click the line to flag it. The total shows $ with en-US separators. German formatting is 1.298,98 €, and the line item above it, 79,98 €, already shows the correct convention.
  2. 2
    Scan every line for leftover English. Flag "3 item(s)" and the Rückgabe line. "item(s)" is the untranslated source string dodging plural grammar with a parenthesis. The returns note mixes German and English because code assembled the sentence: only the outer fragment reached a translator.
  3. 3
    Check the date next to "Lieferung:", then the pay button and the quoted shipping option. 07/17/2026 is month-first en-US order, while a German reader expects 17.7.2026. The button clips its German label at a fixed width, and "Standardversand" carries ASCII quotes where German writes „…“.
  4. 4
    Switch to the "ar-EG · Egypt" tab. If the screen looks fine, press "Show hints". Three bugs live here. The page reads right to left: check where the back control sits, which way the stepper arrows run, and which side of the digits the $ landed on in the total. The Arabic-Indic date, though, is exactly what Intl.DateTimeFormat('ar-EG') produces: leave it alone.
  5. 5
    On the "ja-JP · Japan" tab, run the names-and-input part of the checklist: field order, postal code length, and the extras line. The form asks for the given name first (Japan writes family name first), the postal field caps at 5 digits where Japan needs 7 (NNN-NNNN), and the extras list still joins with an English "and".
  6. 6
    Press "Check my audit", read the tally, then press "Reveal the answer key" for anything still hidden. The tally reads N of 12 found. Flagged decoys cost nothing and explain why they were correct. Missed bugs appear in amber where they sit, and each one links back to the chapter that covers its failure class.

Every line of the screen below was rendered by code as shipped: some of it ran the wrong locale, the wrong CSS, or no translation at all. Click a line to flag it, and again to unflag. Work all three markets, then check the audit. Flagging a correct line costs nothing.

0 flagged across three markets. There are 12 seeded bugs.

shop.example/checkoutde-DE
← Zurück

Kasse

Warenkorb → Versand → Zahlung

Bestellübersicht

Kabellose Maus × 279,98 €
Mechanische Tastatur × 11.219,00 €
3 item(s)
Lieferung: 07/17/2026
Rückgabe innerhalb von 30 days
Sie haben "Standardversand" gewählt.
Gesamt$1,298.98
VornameNachname
PLZ5-stellig

The short version

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.

What to do about it

  • Before any market launch, walk each localized screen with a fixed checklist: numbers, dates, plurals, direction, layout, names, input.
  • For every suspicious value, check what the locale's own formatter produces (Intl.NumberFormat, Intl.DateTimeFormat, Intl.ListFormat). Flag deviations from that output, not deviations from English.
  • Run a pseudolocalization pass before translation starts. It finds the concatenation and hardcoded-string bugs on this screen without a translator.
  • Budget a native-speaker review per market. Automated checks cover formatters, not register, word choice, or honorifics.

Where this comes up

Who it concerns

QAEngineeringLocalization PM

Moments

  • ·Pre-launch market readiness review
  • ·Defining the i18n QA checklist for a release
  • ·Onboarding reviewers who will audit localized builds

Field note

Amazon opened amazon.se in October 2020 with a catalog machine-translated into Swedish and no market review pass. Launch-day pages rendered product names as vulgarities, translated "Nintendo Switch" games as fit for a "circuit breaker", and the country picker showed Argentina's flag for Sweden. None of it was a translation-engine mystery: every item was the kind of thing a native-conventions audit of the top screens would have caught before launch.

The Local: translation fails on Amazon's new Swedish site ↗

Terms in this chapter

Where to read more

Related chapters