The localization category carries the translation-catalog formats every i18n toolchain has to read, all built from one small message set (a greeting, a name-placeholder welcome, button and menu labels) so you can diff the same content across formats. It covers gettext (a .pot template and a translated .po with plural forms), OASIS XLIFF in both 1.2 and 2.0, Apple .strings, Flutter's .arb (with ICU placeholders and metadata), Android strings.xml (with plurals and a string-array), .NET .resx, and i18next JSON. Each format uses its own native placeholder syntax — %s, %@, {name}, %1$s, {0}, {{name}} — so interpolation handling is exercised too. Beyond the Latin base locales (English and accented Spanish), there are right-to-left variants in Arabic and Hebrew and CJK variants in Japanese and Chinese, for testing bidirectional text, Unicode handling, and font fallback. Fluent .ftl, ICU MessageFormat JSON, plural/select catalogues, deeper RTL packs, and Crowdin/CSV bilingual exports extend the set. Everything is plain text and opens in the in-browser editor — fixtures for testing localization pipelines, translation-memory and CAT tools, catalog converters, and pseudolocalization.
Arabic Android quantity strings: 4 <plurals> blocks with an <item> for each of the 6 CLDR quantities ar actually selects. Rename to plurals.xml and drop into res/values-ar/ to use it as-is.
English Android quantity strings: 4 <plurals> blocks with an <item> for each of the 2 CLDR quantities en actually selects. Rename to plurals.xml and drop into res/values/ to use it as-is.
Japanese Android quantity strings: 4 <plurals> blocks with an <item> for each of the 1 CLDR quantities ja actually selects. Rename to plurals.xml and drop into res/values-ja/ to use it as-is.
Polish Android quantity strings: 4 <plurals> blocks with an <item> for each of the 4 CLDR quantities pl actually selects. Rename to plurals.xml and drop into res/values-pl/ to use it as-is.
Welsh Android quantity strings: 4 <plurals> blocks with an <item> for each of the 6 CLDR quantities cy actually selects. Rename to plurals.xml and drop into res/values-cy/ to use it as-is.
An Android values/strings.xml (English) with string resources, a <plurals> block, and a <string-array>, using positional %1$s placeholders — the res/values/ default catalog.
Every escaping rule aapt2 enforces on a strings.xml, in one file: backslash-escaped apostrophes and quotes, quoted values that preserve leading whitespace, an escaped @ and ?, CDATA-wrapped inline HTML, <xliff:g> placeholder protection with examples, formatted="false", translatable="false" and a scoped tools:ignore.
An Apple Localizable.strings file (English) — quoted key = value pairs with comments and %@ placeholders, as iOS/macOS apps use per-locale in .lproj folders.
A German .strings file whose replace_confirm value puts %2$@ before %1$@, because German inverts the pair English uses. Also covers %% as a literal percent, an escaped double quote, a doubled-backslash UNC path and an escaped newline inside a value.
The encoding fixture the .strings format needs: a Japanese catalog written as UTF-16 Little Endian with a byte-order mark, which is what Xcode has historically produced and what a UTF-8-only reader turns into mojibake or a decode error. Also carries full-width punctuation and an ideographic space for width and line-breaking tests.
Arabic Apple plural rules as a .stringsdict property list — the only place iOS and macOS accept plural variants, since a plain .strings file has no plural concept at all. Ships as .xml because the bytes are an XML plist; rename to Localizable.stringsdict to use it.
English Apple plural rules as a .stringsdict property list — the only place iOS and macOS accept plural variants, since a plain .strings file has no plural concept at all. Ships as .xml because the bytes are an XML plist; rename to Localizable.stringsdict to use it.
Polish Apple plural rules as a .stringsdict property list — the only place iOS and macOS accept plural variants, since a plain .strings file has no plural concept at all. Ships as .xml because the bytes are an XML plist; rename to Localizable.stringsdict to use it.
Russian Apple plural rules as a .stringsdict property list — the only place iOS and macOS accept plural variants, since a plain .strings file has no plural concept at all. Ships as .xml because the bytes are an XML plist; rename to Localizable.stringsdict to use it.
Welsh Apple plural rules as a .stringsdict property list — the only place iOS and macOS accept plural variants, since a plain .strings file has no plural concept at all. Ships as .xml because the bytes are an XML plist; rename to Localizable.stringsdict to use it.
Mirroring is a rendering property of the bidi algorithm, not a transformation of the text: a U+0028 LEFT PARENTHESIS inside an RTL run is DRAWN as ')' while the stored byte never changes. These Hebrew and Arabic lines make that testable, and list the neutral characters that look like they should mirror but do not.
Six Arabic sentences containing a Latin filename, a phone number, a version range, a mixed-script path, a percentage and a bracketed insertion — each shown first as a translator usually delivers it and then with the one invisible character that makes it render correctly. The two forms differ by exactly one code point.
Three notification templates in English, Arabic and Hebrew, each given raw and with every interpolation slot wrapped in FSI…PDI, plus four argument sets covering an LTR name in an RTL sentence, an RTL name in an LTR sentence and a name beginning with a neutral character. This is the fixture for the bug where a display name reorders the sentence around it.
A flat index of the bidi cases in this wave — which mark each one uses, what it should render as, and why the neutral characters involved need help. Row b8 is the control case with no marks, against which the other seven are compared.
The HTML half of bidi handling: paragraphs with dir=ltr, dir=rtl and dir=auto, the same user-supplied string with and without a <bdi> wrapper, one balanced <bdo> showing display override scoped to a single element, and explicit RLM/FSI marks inside markup. No scripts and no external resources.
A reference sheet in which each of the ten shipped bidi control characters appears literally between ASCII guards, with its code point, UTF-8 bytes and the job it does. The two override characters are named but deliberately absent: a bidi rendering fixture does not need to ship the Trojan Source vector.
Arabic CLDR cardinal and ordinal plural rules with the exact integer samples that select each category, the equivalent gettext Plural-Forms expression, and a note on the trap the language exposes: a catalog written with only one/other silently renders 'many' counts (11-99) with the singular noun form.
English CLDR cardinal and ordinal plural rules with the exact integer samples that select each category, the equivalent gettext Plural-Forms expression, and a note on the trap the language exposes: '1.
Japanese CLDR cardinal and ordinal plural rules with the exact integer samples that select each category, the equivalent gettext Plural-Forms expression, and a note on the trap the language exposes: japanese needs exactly one form; a pipeline that requires a 'one' key produces a catalog no japanese translator can fill in meaningfully.
Polish CLDR cardinal and ordinal plural rules with the exact integer samples that select each category, the equivalent gettext Plural-Forms expression, and a note on the trap the language exposes: cldr gives polish four categories but the traditional gettext header gives it three — gettext folds cldr 'many' and 'other' together because its rule takes an integer n and never sees v.
Russian CLDR cardinal and ordinal plural rules with the exact integer samples that select each category, the equivalent gettext Plural-Forms expression, and a note on the trap the language exposes: 1 and 21 take the same form but 11 does not; a naive n==1 check gets 21 wrong.
Welsh CLDR cardinal and ordinal plural rules with the exact integer samples that select each category, the equivalent gettext Plural-Forms expression, and a note on the trap the language exposes: welsh is the only cldr locale using all six categories for both cardinals and ordinals, and its categories are enumerations (3, 6) rather than modulo ranges — a rule engine that assumes 'few' means a range fails here.
One row per language, one column per CLDR plural category, filled with the smallest integers that select it — the sheet to hand a translator or a PM when explaining why 'one' and 'other' is not enough. Japanese needs one form and Welsh needs six.
A Arabic (Egypt) resource file built around composite format strings — {0:N2}, {2:P1}, {0:C}, {0:d} and {0:t} — whose rendered output depends entirely on CultureInfo. Includes a whitespace-significant resource guarded by xml:space, and documents the suffixed-key convention .NET falls back on because String.Format has no plural selector.
A English (United States) resource file built around composite format strings — {0:N2}, {2:P1}, {0:C}, {0:d} and {0:t} — whose rendered output depends entirely on CultureInfo. Includes a whitespace-significant resource guarded by xml:space, and documents the suffixed-key convention .NET falls back on because String.Format has no plural selector.
A German (Germany) resource file built around composite format strings — {0:N2}, {2:P1}, {0:C}, {0:d} and {0:t} — whose rendered output depends entirely on CultureInfo. Includes a whitespace-significant resource guarded by xml:space, and documents the suffixed-key convention .NET falls back on because String.Format has no plural selector.
A Polish (Poland) resource file built around composite format strings — {0:N2}, {2:P1}, {0:C}, {0:d} and {0:t} — whose rendered output depends entirely on CultureInfo. Includes a whitespace-significant resource guarded by xml:space, and documents the suffixed-key convention .NET falls back on because String.Format has no plural selector.
A .NET Resources.resx file (English) with the standard ResX schema and resheader block plus name/value string data and comments, using {0} composite-format placeholders.
A Flutter Application Resource Bundle (English) — JSON messages with matching @key metadata (descriptions and typed placeholders) using ICU {name} syntax, as Flutter's gen-l10n consumes.
A Arabic ARB whose plural messages carry an ICU branch for each of the 6 categories ar selects, plus a select message and a summary line with typed placeholders — int with compactLong, and a DateTime with a yMMMd format — which is what makes gen_l10n emit a typed Dart method rather than a plain string.
A English ARB whose plural messages carry an ICU branch for each of the 2 categories en selects, plus a select message and a summary line with typed placeholders — int with compactLong, and a DateTime with a yMMMd format — which is what makes gen_l10n emit a typed Dart method rather than a plain string.
A Polish ARB whose plural messages carry an ICU branch for each of the 4 categories pl selects, plus a select message and a summary line with typed placeholders — int with compactLong, and a DateTime with a yMMMd format — which is what makes gen_l10n emit a typed Dart method rather than a plain string.
A Welsh ARB whose plural messages carry an ICU branch for each of the 6 categories cy selects, plus a select message and a summary line with typed placeholders — int with compactLong, and a DateTime with a yMMMd format — which is what makes gen_l10n emit a typed Dart method rather than a plain string.
12345.60 in each locale's own currency, with the fraction-digit count and the symbol placement that produced it. JPY takes zero decimals and rounds; six rows separate the amount from the symbol with U+00A0 rather than a plain space; and ar-EG puts the amount in Arabic-Indic digits.
The structured currency table with the three traps spelled out: minor units belong to the CURRENCY not the locale (JPY 0, USD 2, KWD/BHD/JOD 3), the gap before a trailing symbol is U+00A0 in six of these locales, and CLDR's ar-EG pattern contains an invisible U+200F that breaks naive equality assertions.
Short and medium date patterns, the short time pattern and the hour cycle for ten locales, each with the rendering of 2026-03-14T09:05. The ar-EG patterns contain U+200F between their fields and ru-RU's medium pattern ends in a quoted literal, so neither is the plain ASCII it appears to be.
The structured date table plus the four traps worth their own test: day/month ambiguity in short dates, the RLM embedded in CLDR's Arabic pattern, quoted literal text inside the Russian pattern, and the localized day-period marker that a 12-hour formatter must not drop.
The same number, 1234567.89, rendered for twelve locales, with the group and decimal separator that produced each one named by code point and present literally in the cell. Four of the separators are not ASCII — U+00A0, U+202F, U+2019 and U+066C — and ar-EG additionally switches the digits themselves.
The structured twin of the number-format table, plus four documented traps: es-ES's minimumGroupingDigits=2 (which leaves a four-digit integer ungrouped), the four non-ASCII group separators, the arab numbering system's own digits, and the seven locales here whose decimal separator is a comma.
Every separator, sign and digit set a locale-aware formatter has to survive, each present literally between ASCII guards: the no-break and narrow-no-break spaces, de-CH's U+2019 group separator, the Arabic decimal and thousands separators, the four numbering systems' digits, and CLDR's U+2212 MINUS SIGN, which is not the ASCII hyphen.
Era and era-year for one instant across five calendar systems. The three whose months and days align with the Gregorian calendar — Japanese (Reiwa 8), ROC (Minguo 115) and Thai Buddhist (2569) — carry a full rendered date; the Hijri and Hebrew entries carry the year only, because their day and month depend on the calculation variant and, for Hijri, on observation. Saying so is the point of the fixture.
A translated gettext .po catalog (Spanish) with a full header, source-location and translator comments, c-format flags, and a plural-form entry — for testing PO parsers and translation-memory tools.
The compiled Arabic MO twin. Plural entries are encoded the way msgfmt does it — the original is 'singular\\0plural' and the translation is the 6 forms joined by NUL — and the header entry carries the Plural-Forms expression, so ngettext resolves without the .po file present.
The compiled Polish MO twin. Plural entries are encoded the way msgfmt does it — the original is 'singular\\0plural' and the translation is the 3 forms joined by NUL — and the header entry carries the Plural-Forms expression, so ngettext resolves without the .po file present.
The compiled Russian MO twin. Plural entries are encoded the way msgfmt does it — the original is 'singular\\0plural' and the translation is the 3 forms joined by NUL — and the header entry carries the Plural-Forms expression, so ngettext resolves without the .po file present.
The compiled Welsh MO twin. Plural entries are encoded the way msgfmt does it — the original is 'singular\\0plural' and the translation is the 6 forms joined by NUL — and the header entry carries the Plural-Forms expression, so ngettext resolves without the .po file present.
A German catalog carrying every state a PO entry can be in but the happy one: two fuzzy entries (one of them a plural) with #| previous-msgid comments, an entry that is present but untranslated, three obsolete #~ entries including an obsolete plural and an obsolete msgctxt entry, and two complete entries as the control.
The English word "Open" translated four different ways in one file — three msgctxt variants plus the context-free entry — alongside a multi-line msgid that must be concatenated with no separator, a no-c-format entry whose %% is literal text, and explicit tab and quote escapes with a significant trailing space.
A Arabic gettext catalog with a real Plural-Forms header and 6 msgstr[] forms per plural entry, source-location and extracted comments, and c-format flags. Pairs with the compiled .mo of the same content, so a loader can be tested end to end rather than on the text format alone.
A Polish gettext catalog with a real Plural-Forms header and 3 msgstr[] forms per plural entry, source-location and extracted comments, and c-format flags. Pairs with the compiled .mo of the same content, so a loader can be tested end to end rather than on the text format alone.
A Russian gettext catalog with a real Plural-Forms header and 3 msgstr[] forms per plural entry, source-location and extracted comments, and c-format flags. Pairs with the compiled .mo of the same content, so a loader can be tested end to end rather than on the text format alone.
A Welsh gettext catalog with a real Plural-Forms header and 6 msgstr[] forms per plural entry, source-location and extracted comments, and c-format flags. Pairs with the compiled .mo of the same content, so a loader can be tested end to end rather than on the text format alone.
A gettext .pot template extracted from source — msgid entries with empty msgstr values, source-location comments, and a plural form — the starting point for a new language translation.
The quoting rules that make ICU messages surprising: a single quote starts a literal section only when the next character is one ICU cares about, a doubled '' is always one apostrophe, and '#' inside a plural branch is a literal hash. Every message is paired with the exact string it must produce.
Arabic ICU MessageFormat catalog whose messages nest a select inside a plural branch and a plural inside a select branch, shipped with the argument bindings and the exact output each one must produce. Includes the '#' binding trap: inside a nested plural, '#' refers to the inner argument, so the outer count is written explicitly.
English ICU MessageFormat catalog whose messages nest a select inside a plural branch and a plural inside a select branch, shipped with the argument bindings and the exact output each one must produce. Includes the '#' binding trap: inside a nested plural, '#' refers to the inner argument, so the outer count is written explicitly.
Polish ICU MessageFormat catalog whose messages nest a select inside a plural branch and a plural inside a select branch, shipped with the argument bindings and the exact output each one must produce. Includes the '#' binding trap: inside a nested plural, '#' refers to the inner argument, so the outer count is written explicitly.
The 'Rana and 5 others like this' pattern: ICU plural arguments with offset:1 and offset:2, where the explicit =0/=1/=2 selectors match the RAW value but '#' prints the value MINUS the offset. Ships every boundary case with its expected output.
Welsh is the only CLDR locale that uses all six plural categories for cardinals AND all six for ordinals, which makes it the strongest single probe for a plural-rule engine. Each branch names its own category so the assertion is about selection, not wording, and the two rule sets disagree for n = 4, 5, 7, 8 and 9.
English st/nd/rd/th suffixes done properly, via ICU selectordinal rather than a hand-written switch. The case list covers the teens (11th, 12th, 13th) and the wrap-around (21st, 102nd, 111th) that a naive n % 10 lookup gets wrong.
A English Java ResourceBundle with MessageFormat patterns, a ChoiceFormat plural, positional arguments, escaped braces and apostrophes, a backslash line continuation, and non-ASCII carried as \uXXXX escapes because .properties is defined as ISO-8859-1. The bytes on disk are pure ASCII.
File
PROPERTIES · Icu · ISO-8859-1, non-ASCII written as \uXXXX escapes
A German Java ResourceBundle with MessageFormat patterns, a ChoiceFormat plural, positional arguments, escaped braces and apostrophes, a backslash line continuation, and non-ASCII carried as \uXXXX escapes because .properties is defined as ISO-8859-1. The bytes on disk are pure ASCII.
File
PROPERTIES · Icu · ISO-8859-1, non-ASCII written as \uXXXX escapes
The XLIFF 1.2 half of a version twin covering how each version represents inline markup and placeholders. XLIFF 1.2 keeps the original markup inline in <bpt>/<ept> and uses <g>, <x/> and <ph>; XLIFF 2.0 replaced all of them with <pc>, <ph/>, <sc/>/<ec/> and moved the markup into an <originalData> block referenced by id.
The XLIFF 1.2 half of a version twin covering how each version expresses a plural group. XLIFF 1.2 uses a <group restype="x-gettext-plurals"> whose trans-units are ordered by gettext form index; XLIFF 2.0 dropped restype, so the same content becomes one <unit> per CLDR category, named by category rather than by index.
The XLIFF 1.2 half of a version twin covering how each version records translation progress. XLIFF 1.2 has approved="yes|no" plus a ten-value target state; XLIFF 2.0 removed approved and cut the vocabulary to four ordered values (initial, translated, reviewed, final) with everything else pushed into a namespaced subState.
An OASIS XLIFF 1.2 file with English source and Spanish target trans-units and notes — the classic interchange format between authoring tools and translation-management systems.
The XLIFF 2.0 half of a version twin covering how each version represents inline markup and placeholders. XLIFF 1.2 keeps the original markup inline in <bpt>/<ept> and uses <g>, <x/> and <ph>; XLIFF 2.0 replaced all of them with <pc>, <ph/>, <sc/>/<ec/> and moved the markup into an <originalData> block referenced by id.
The XLIFF 2.0 half of a version twin covering how each version expresses a plural group. XLIFF 1.2 uses a <group restype="x-gettext-plurals"> whose trans-units are ordered by gettext form index; XLIFF 2.0 dropped restype, so the same content becomes one <unit> per CLDR category, named by category rather than by index.
The XLIFF 2.0 half of a version twin covering how each version records translation progress. XLIFF 1.2 has approved="yes|no" plus a ten-value target state; XLIFF 2.0 removed approved and cut the vocabulary to four ordered values (initial, translated, reviewed, final) with everything else pushed into a namespaced subState.
An OASIS XLIFF 2.0 file with the same content as its 1.2 twin, using the modern unit/segment structure — for testing XLIFF 2.0 parsers and 1.2-to-2.0 converters.
Gettext PO/POT, XLIFF, Apple strings, Flutter ARB, Android XML, RESX, i18next JSON, plus Fluent .ftl, ICU MessageFormat JSON, bilingual CSV, and Crowdin-shaped exports.
Do you include RTL locales?+
Yes — Arabic, Hebrew, Persian, and Urdu UI packs with dir=rtl for bidirectional layout tests.
We use Google Analytics and show ads via Adsterra. Non-essential cookies and ad scripts run only after you allow the matching categories. See our cookie policy.