Laravel localization in Chinese (Simplified) 简体中文
Everything you need to ship Chinese (Simplified) in a Laravel app: the right locale codes,
the exact plural forms trans_choice() expects,
real localized Carbon output and Han (Simplified)-script considerations.
Every value on this page was generated by running ICU, CLDR and Carbon — not copied from another article.
ISO 639-1
zh
Script / Direction
Han (Simplified) · LTR
Plural forms (Laravel)
1
Text vs English
Contracts
Locale codes
Set the base locale in config/app.php. For regional variants,
Chinese (Simplified) commonly uses:
zh_CN, zh_SG
// config/app.php
'locale' => 'zh',
'fallback_locale' => 'en',
// Or switch at runtime
App::setLocale('zh');
Plural rules: what Chinese (Simplified) actually needs
CLDR defines 1 cardinal category for Chinese (Simplified). The sample numbers below were computed by ICU for this exact locale:
| CLDR category | Numbers that select it |
|---|---|
| other | 0–130, 200, 1000, 1000000, 1.5 |
Laravel's trans_choice() maps numbers to
1 pipe-separated
form for this locale:
| Form index | Numbers that select it |
|---|---|
| 0 | 0–130, 200, 1000 |
// lang/zh/messages.php
'items' => ':count'
// Usage
trans_choice('messages.items', $count, ['count' => $count]);
This language has no grammatical plural, so a single form covers every number.
Try any number live in the pluralization tester.
Localized dates with Carbon
Real output for Chinese (Simplified) (zh_CN locale),
generated by Carbon for March 21, 2026:
$date = now()->locale('zh_CN');
$date->translatedFormat('l, j F Y');
// "星期六, 21 三月 2026"
$date->isoFormat('LLLL');
// "2026年3月21日星期六下午2点30分"
$date->isoFormat('L');
// "2026/03/21"
$date->subDays(3)->diffForHumans();
// "3个月前"
What to watch out for in Chinese (Simplified)
- No spaces between words; line breaking is character-based, and full-width punctuation (。,、) is standard.
- No plural, gender, or tense inflection; measure words are required between numbers and nouns (3 个项目).
- Simplified characters are used in mainland China and Singapore; Traditional Chinese (zh_TW, zh_HK) is a separate target, not a variant of this locale.
- Dates are written year-first (2026年3月1日).
Simplified and Traditional are not a formatting switch
Chinese is written in two character sets. Simplified is used in mainland China and Singapore; Traditional is used in Taiwan, Hong Kong and Macau. Converting between them is not a character-for-character mapping, and treating it as one produces text that is recognisably machine-converted.
Several Simplified characters merge multiple Traditional ones, so the reverse conversion is ambiguous and needs context. The character 发 corresponds to both 發 (to send) and 髮 (hair), and 干 covers 乾, 幹 and 干. A one-to-one table gets these wrong at a predictable rate.
Vocabulary diverges as well, particularly in technology, which is exactly the domain your interface occupies.
| English | Mainland (zh-Hans) | Taiwan (zh-Hant-TW) |
|---|---|---|
| software | 软件 | 軟體 |
| network | 网络 | 網路 |
| video | 视频 | 影片 |
| information | 信息 | 資訊 |
| mouse | 鼠标 | 滑鼠 |
Note that the last two rows differ in word choice, not only in character form, so no script conversion produces them. Treat zh-Hans and zh-Hant as separate locales with separate translations, and be aware that Hong Kong Traditional differs from Taiwan Traditional in vocabulary again.
Use script subtags rather than country codes where you can. zh-Hans and zh-Hant describe what actually differs, while zh-CN and zh-TW conflate script with market and leave Singapore and Hong Kong ambiguous.
No spaces, no plurals, no inflection
Chinese is analytic and isolating: words do not inflect at all. There is no plural marking, no verb conjugation, no tense inflection, no gender and no case. CLDR gives Chinese a single plural category, so trans_choice() takes one form for every number.
One form for every count
// lang/zh_CN/messages.php
'files' => ':count 个文件',
// 0 -> 0 个文件
// 1 -> 1 个文件
// 42 -> 42 个文件
Measure words carry the load that inflection carries elsewhere. A number cannot attach directly to a noun; a classifier goes between them, chosen by the nature of the thing counted.
| Classifier | Used for | Example |
|---|---|---|
| 个 | Generic default | 3 个文件 |
| 位 | People (respectful) | 3 位用户 |
| 张 | Flat things: images, cards | 3 张图片 |
| 条 | Long thin things, messages, records | 3 条消息 |
| 台 | Machines, devices | 3 台设备 |
| 次 | Occurrences, attempts | 3 次尝试 |
个 is the general-purpose classifier and is acceptable in many contexts, which makes Chinese more forgiving here than Japanese or Korean. It is still noticeably wrong in some cases — 条 for messages and 张 for images are strongly expected — so a single shared counting string produces copy that reads as slightly off rather than as broken.
Chinese is written without spaces between words, so whitespace-based word counts, truncation and search tokenisation all fail in the same way as in Thai and Japanese. Search needs a Chinese analyser doing dictionary or n-gram segmentation; a whitespace tokeniser will index entire sentences as single terms.
Typography and layout
Chinese is the most compact language you are likely to support. Character counts run forty to sixty per cent below English, though each character occupies a full-width cell, so rendered width lands roughly at or below the English original. Overflow is rare and under-filled containers are the more common problem — a button sized for "Settings" looks empty holding 设置.
Vertical space is the constraint instead. Chinese characters are dense, with some containing more than twenty strokes in a single cell, and they become genuinely illegible at small sizes that work fine for Latin text. Set a minimum font size for Chinese rather than inheriting the Latin scale, and give generous line height.
Punctuation is full-width and distinct from the Latin equivalents. The Chinese comma is ,not ,; the full stop is 。not .; quotation marks are “ ” or 「 」. These are different code points and mixing Latin punctuation into Chinese text reads as careless, so any normalisation routine that converts punctuation must leave Chinese text alone.
Line breaking follows its own rules, since a break may occur between almost any two characters but must not leave certain punctuation at the start of a line. Browsers handle this correctly when the language is declared, so lang="zh-Hans" is doing real work rather than being metadata.
There is no bold or italic tradition in Chinese typography. Synthesised bold thickens strokes until dense characters become an unreadable blur, and synthesised italics look wrong. Use colour, size or a different weight of a font designed for it.
Input, sorting and names
Chinese text entry goes through an input method that converts pinyin or another phonetic input into characters, with the user choosing among candidates. Any JavaScript reacting to every keystroke will fire on the intermediate Latin text before conversion, so live search, character counters and inline validation must respect composition events.
Wait for the input method to commit
let composing = false
input.addEventListener('compositionstart', () => composing = true)
input.addEventListener('compositionend', () => {
composing = false
search(input.value)
})
input.addEventListener('input', () => {
if (!composing) search(input.value)
})
Sorting has no single obvious answer. Chinese can be ordered by pinyin, by stroke count or by radical, and users expect different orders in different contexts — pinyin for name lists, stroke count for formal and official listings. Byte order is meaningless. Use a collator with an explicit ordering rather than accepting a default.
Names are written family name first with no space: 王小明 has the surname 王. Surnames are usually one character and given names one or two, and the pool of surnames is small enough that collisions are constant — a handful of surnames cover a very large share of the population.
Form design should account for that shape. A layout assuming a long given name and a distinguishing surname fits Chinese names poorly, and code assembling a display name given-first produces a name that reads as reversed.
Storage needs utf8mb4 without exception. Many Chinese characters, including ones used in personal names, sit outside the Basic Multilingual Plane, and MySQL's three-byte utf8 will reject or truncate them — affecting precisely the users whose names are unusual.
Formatting and the numbers that group in fours
Chinese groups large numbers in units of ten thousand rather than of a thousand. 万 is ten thousand and 亿 is a hundred million, so a Chinese reader parses 1,0000 as one 万 where a Western reader parses 10,000 as ten thousand.
Displayed digits generally still use Western three-digit grouping in software, so this rarely breaks formatting outright. It matters when numbers are written out or abbreviated: a summary showing 12.3万 is natural Chinese, while 123K is not, and a dashboard abbreviating large figures with K and M reads as untranslated.
| Mainland convention | |
|---|---|
| Thousands | 1,234,567 |
| Decimal | 1234.56 |
| Currency | ¥1,234.56 |
| Large numbers | 12.3万 rather than 123K |
| Short date | 2026/3/21 or 2026-03-21 |
| Long date | 2026年3月21日 |
| First day of week | Monday |
Dates run largest unit first with the markers 年, 月 and 日, which aligns with ISO order and makes Chinese one of the least ambiguous locales for dates. Numbers otherwise follow English conventions, so there is no decimal-comma hazard.
Note that ¥ is ambiguous between the Chinese yuan and the Japanese yen. Where both currencies may appear, use the explicit codes CNY and JPY, or the Chinese-specific 元 marker, rather than relying on the shared symbol.
Practicalities of shipping into mainland China
Chinese localisation has an operational dimension that most locales do not, and it affects whether the translated product is usable at all rather than merely whether it reads well.
Third-party assets are the immediate issue. Google Fonts, Google-hosted script CDNs, and several common analytics and map providers are not reliably reachable from mainland China, so a page that renders instantly elsewhere may hang for seconds or fall back to system fonts. Self-host fonts and scripts, or serve them from a CDN with mainland presence, and verify from inside the network rather than assuming.
Web font size deserves separate thought. A Chinese font covering the common character set is measured in megabytes rather than kilobytes, since it needs thousands of glyphs rather than a hundred or so. Subsetting to the characters actually used in your interface is worthwhile, and for user-generated content a system font stack is usually the right choice — the platform fonts are good and already installed.
Phone numbers, addresses and identity formats differ enough to break validation written for Western markets. Chinese addresses run largest unit first — province, city, district, street — which is the reverse of a Western address form, and a form laid out in Western order confuses users even when every label is translated.
Finally, set the locale with a script subtag and store it that way. A user preference recorded as zh is ambiguous about script, and the ambiguity surfaces the first time you add Traditional — at which point every stored preference needs interpreting rather than reading.
What ships broken most often
- Traditional generated from Simplified by table lookup. Ambiguous merges converted wrongly, and vocabulary left mainland.
- Latin punctuation inside Chinese text. A comma or full stop that should be full-width.
- Live search firing during input-method composition. Queries sent for pinyin the user has not converted yet.
- Synthesised bold on dense characters. Strokes merging into an unreadable blob.
- Font size inherited from the Latin scale. Complex characters illegible at small sizes.
- K and M abbreviations. Chinese readers expect 万 and 亿.
- Three-byte utf8 storage. Rejecting or truncating names containing characters outside the BMP.
The script decision is the one to make deliberately and early. Committing to Simplified alone is entirely reasonable for a mainland-focused product, but discovering later that Taiwan and Hong Kong need their own locales — with their own vocabulary rather than a converted script — is a translation project rather than a configuration change.
Framework strings already translated
Laravel's own validation, auth and pagination strings are maintained in Chinese (Simplified) by the open-source Laravel-Lang project (MIT). Install them, then manage your app's own strings live:
composer require laravel-lang/common --dev
php artisan lang:add zh
php artisan lang:update
Translate your app into Chinese (Simplified) today
Import your lang files, translate every key into Chinese (Simplified) with one AI click, and publish changes live — no deploy. Set up in 5 minutes.