"Chinese" is not one locale — it's three
Pick "Chinese" in a generic BYO-key translation utility and you get one file. That is the single most expensive mistake in a Chinese launch, because a mainland reader and a Taiwan reader do not read the same script, and a Hong Kong reader reads Traditional characters with mainland-leaning vocabulary. strings.dev ships these as three first-class locales:
- zh-Hans — Simplified script, mainland China (Android
values-b+zh+Hans, legacy values-zh-rCN)
- zh-Hant — Traditional script, Taiwan (
values-b+zh+Hant, legacy values-zh-rTW)
- zh-HK — Traditional script, Hong Kong; Apple language ID
zh-HK, BCP-47 zh-Hant-HK
Full code mappings live in the locale codes reference.
It's characters and words, not a font
Simplified and Traditional are different character sets — 电 vs 電, 门 vs 門 — so you cannot render one from the other by swapping a typeface. On top of the script split, everyday tech vocabulary diverges between regions:
| English |
zh-Hans (mainland) |
zh-Hant (Taiwan) |
zh-HK (Hong Kong) |
| software |
软件 |
軟體 |
軟件 |
| network |
网络 |
網路 |
網絡 |
| information |
信息 |
資訊 |
資訊 |
| video |
视频 |
影片 |
影片 |
A Taiwan user who sees 软件 (mainland "software") reads it as foreign, the same way a British user clocks "color." That is exactly why collapsing to one "Chinese" file undercuts the localization you paid for — the script is only half of it.
A real string: placeholder intact, half the width
Here is an iOS source string and its actual Simplified translation. The %@ and %lld tokens survive unchanged, surrounded by full-width Chinese punctuation (,!。):
// English source — Base.lproj
"inbox_summary" = "Welcome back, %@! You have %lld new messages.";
// Simplified Chinese — zh-Hans.lproj
"inbox_summary" = "欢迎回来,%@!您有 %lld 条新消息。";
Strip the placeholders and the 44-character English string collapses to just 10 Han characters (欢迎回来 · 您有 · 条 · 新消息). Raw glyph count makes that look like ~75% shorter, but each Han character renders full-width — roughly two Latin characters wide — so the translated line still lands at about 40–50% of the English pixel width. That width compression is typical of CJK text and is the layout fact that bites indie apps. strings.dev keeps %@, %lld, %1$@ (and Android %s, %d, %1$s) as literal ASCII tokens even when they are wedged between full-width characters — a spot where naive machine translation loves to widen %@ into full-width %@ and crash your formatter.
Measure words and a single plural
Two Chinese-specific rules change how your count strings translate:
- One plural category. Chinese has only the CLDR
other form — there is no singular/plural inflection. "1 message" and "9 messages" use the identical noun. On Android your <plurals> needs just one <item quantity="other">; on iOS a String Catalog variation for Chinese only needs the other case. No one/few/many scaffolding to fill in.
- Classifiers (量词). A counted noun takes a measure word between the number and the noun. In the string above,
%lld 条新消息 uses 条 (tiáo), the classifier for messages; Taiwan would write %lld 則新訊息, with a different classifier and a different word for "message." A translator that drops the classifier produces text that reads as broken to a native speaker — so the count word matters as much as the number itself.
Design for compression before you translate
Because Chinese renders so much narrower, UI sized for English looks under-filled: a button labeled 保存 (Save) floats in a box built for eight Latin characters. Two practical moves before you localize:
- Let containers shrink-to-fit or center short CJK labels instead of hard-coding widths.
- Raise your minimum font size for Chinese — dense strokes at 11pt turn to mud where the same size reads fine in Latin. Chinese also has no spaces between words and wraps per-character, so line-break logic tuned for spaces behaves differently.
Feed your app description into strings.dev as context and the model disambiguates terms that are wrong out of context — 应用 (app) vs 申请 (application form), 主页 (home screen) vs 首页 (website home page) — instead of coin-flipping.
Storefronts are separate — and advisory
The App Store and Play Store treat mainland China, Taiwan, and Hong Kong as distinct storefronts with their own metadata slots. That is useful context for planning which of the three locales to ship first, but store listings are a separate surface: strings.dev localizes your in-app .xcloc / .xcstrings and strings.xml only. Store titles, descriptions, and screenshots stay your own workflow.
Adding Chinese to your app
The free Indie tier covers 1 project and 1 language with unlimited words. Your first language — say zh-Hans — is free. Because Simplified, Traditional, and Hong Kong are three separate locales, shipping the full Chinese matrix means going past that one free language: Indie Plus unlocks unlimited languages, 2 projects, brand context, and the QA dashboard for $20/mo, or $10/mo billed annually (pricing). Upload your existing export, pick the zh variants you need, and get native files back in the same format.