Laravel localization in Thai ไทย
Everything you need to ship Thai in a Laravel app: the right locale codes,
the exact plural forms trans_choice() expects,
real localized Carbon output and Thai-script considerations.
Every value on this page was generated by running ICU, CLDR and Carbon — not copied from another article.
ISO 639-1
th
Script / Direction
Thai · LTR
Plural forms (Laravel)
1
Text vs English
Similar
Locale codes
Set the base locale in config/app.php. For regional variants,
Thai commonly uses:
th_TH
// config/app.php
'locale' => 'th',
'fallback_locale' => 'en',
// Or switch at runtime
App::setLocale('th');
Plural rules: what Thai actually needs
CLDR defines 1 cardinal category for Thai. 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/th/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 Thai (th locale),
generated by Carbon for March 21, 2026:
$date = now()->locale('th');
$date->translatedFormat('l, j F Y');
// "เสาร์, 21 มีนาคม 2026"
$date->isoFormat('LLLL');
// "Lันเสาร์ที่ 21 มีนาคม 2026 เวลา 14:30"
$date->isoFormat('L');
// "21/03/2026"
$date->subDays(3)->diffForHumans();
// "3 เดือนที่แล้ว"
What to watch out for in Thai
- No spaces between words (spaces separate phrases), so line breaking requires dictionary-based word segmentation.
- No plural, gender, or tense inflection; meaning comes from context and helper words.
- Polite particles (ครับ for male, ค่ะ for female speakers) set register in user-facing text.
- The Buddhist Era calendar (year + 543) is widely used in formal Thai dates.
No spaces between words, and no reliable way to add them
Thai is written without spaces between words. Spaces exist, but they mark the end of a clause or sentence rather than a word boundary, so whitespace carries roughly the weight of a comma in English. A Thai sentence is an unbroken run of characters that a reader segments by knowing the language.
This breaks more code than it first appears. Word counts computed by splitting on whitespace are meaningless. Truncation at a character count can cut mid-word, producing a fragment that is either nonsense or, worse, a different valid word. Search that tokenises on spaces will index whole clauses as single terms.
Line breaking is the most visible consequence. A browser given Thai text with no language declared has no basis for choosing break points and will either break at arbitrary character boundaries or refuse to break at all, overflowing the container. Declaring the language lets it apply dictionary-based segmentation.
Thai needs the language declared to break correctly
<p lang="th" class="[line-break:loose] [word-break:normal]">
การตั้งค่าบัญชีผู้ใช้ถูกบันทึกแล้ว
</p>
<!-- Without lang="th" the browser has no Thai
dictionary and cannot find word boundaries. -->
For search, a Thai analyser is not optional in the way it is for European languages. Elasticsearch, Meilisearch and most engines ship dictionary-based Thai tokenisers, and without one the index contains clause-length terms that almost never match a user's query.
Where you must truncate in application code, prefer CSS ellipsis so the browser handles the boundary, and treat any server-side character-count limit as approximate rather than as a promise about how the text will read.
Characters stack vertically in four levels
Thai is an abugida with marks placed above and below the base consonant. A single visible cluster can occupy four vertical levels: a below-vowel, the consonant, an above-vowel and a tone mark on top of that.
The practical consequence is that Thai needs substantially more line height than Latin text at the same font size — noticeably more than Devanagari or Arabic. A line height inherited from an English design will clip the tone marks, and since tone marks distinguish words in Thai, clipping is a correctness problem rather than a cosmetic one.
Character-level string manipulation is unsafe for the same reason as in other complex scripts. A visible cluster is several code points, and slicing at a fixed offset can separate a vowel or tone mark from its consonant, producing an orphaned mark that renders as a dotted circle.
Font coverage is worth verifying explicitly. Many fonts advertise Thai support and position the stacked marks poorly, producing text that Thai readers find hard to read even though every glyph is present. Test with real sentences containing tone marks over tall consonants rather than with a character sample.
Thai has no uppercase and lowercase, which removes case-transformation bugs entirely, and no italic tradition — synthesised obliques look wrong. Use weight and colour for emphasis, and scope any text-transform or font-style rules so they do not apply to Thai.
No plurals, no tense, no gender
Thai is analytic: words do not change form. There is no plural marking, no verb conjugation, no grammatical gender and no tense inflection — time is conveyed by adverbs and context. CLDR gives Thai a single plural category, so trans_choice() takes one form for every number.
One form for every count
// lang/th/messages.php
'files' => ':count ไฟล์',
// 0 -> 0 ไฟล์
// 1 -> 1 ไฟล์
// 42 -> 42 ไฟล์
As with the other South-East Asian and East Asian languages, classifiers replace the complexity. Thai requires a measure word after the number, chosen by the nature of the thing counted, and the word order differs from English: noun, number, classifier.
| Classifier | Used for | Example |
|---|---|---|
| อัน | Generic small objects | ไฟล์ 3 อัน |
| คน | People | ผู้ใช้ 3 คน |
| รายการ | List items, records | รายการ 3 รายการ |
| ครั้ง | Occurrences, attempts | 3 ครั้ง |
| เครื่อง | Machines, devices | อุปกรณ์ 3 เครื่อง |
That word order matters for templates. An English string of the form :count files maps to Thai as noun first, then number, then classifier, so a placeholder positioned at the start of the string in English belongs in the middle in Thai. Translators handle this naturally provided the placeholder is free to move — which is another reason to keep whole sentences in one key.
Politeness particles and register
Thai marks politeness with sentence-final particles rather than with verb forms. The particle depends on the gender of the speaker, not the listener: ครับ for a male speaker and ค่ะ for a female one.
For software this is a brand-voice decision rather than a per-user one, since the application is the speaker. Products generally either adopt one particle consistently — ค่ะ is common for service-oriented brands — or omit the particles and use a neutral, slightly formal register throughout, which is standard for interface copy as opposed to conversational copy.
Buttons and labels take no particle at all. They are noun phrases: บันทึก (save), ยกเลิก (cancel), ลบ (delete). Particles belong in full sentences addressed to the user, such as confirmations and error messages, and in conversational surfaces like chat support.
Thai also has a distinct royal and formal vocabulary layer, which appears in official and ceremonial contexts. It is not needed for ordinary software, but it means machine translation trained on mixed corpora occasionally produces inappropriately elevated wording — one more reason a native review pass matters more here than the grammatical simplicity suggests.
The Buddhist calendar and formatting
Thailand uses the Buddhist Era calendar officially, which runs 543 years ahead of the Gregorian one. The year 2026 CE is 2569 BE, and Thai users see BE years on official documents, in the media and in most domestic software.
This is the most consequential formatting difference and the easiest to get wrong, because a date rendered in the Gregorian year is not merely formatted differently — it names a different year. Use the platform's calendar support with the Thai locale rather than adding an offset by hand, and be explicit in your data model about which era a stored date uses.
Buddhist era dates via the locale
<?php
$formatter = new IntlDateFormatter(
'th_TH@calendar=buddhist',
IntlDateFormatter::LONG,
IntlDateFormatter::NONE
);
// 21 มีนาคม 2569 — not 2026
| Thai convention | |
|---|---|
| Calendar | Buddhist Era (CE + 543) |
| Digits | Western (Thai digits ๐–๙ in formal use) |
| Thousands | 1,234,567 |
| Decimal | 1234.56 |
| Currency | ฿1,234.56 |
| Short date | 21/3/2569 |
| First day of week | Sunday |
Numbers follow English conventions, so there is no decimal-comma hazard. Thai digits exist and appear in formal and ceremonial contexts, but Western digits are standard in software and commerce. Thai text runs roughly fifteen per cent shorter than English in visual width, so overflow is uncommon.
Getting Thai into the application
Thai grammar is simple and Thai text handling is not, so the work sits almost entirely in infrastructure rather than in string architecture. Four things account for most of the difference between Thai that works and Thai that does not.
Declare the language on every element containing Thai. This is not metadata: without lang="th" the browser has no dictionary and therefore no word boundaries, so it cannot break lines sensibly, cannot hyphenate, and cannot apply the right font fallback. It is the single highest-value change and it costs one attribute.
Give the text vertical room. Thai stacks to four levels and clipping a tone mark changes the word rather than merely truncating it, so line height needs to be set explicitly for Thai rather than inherited from a Latin scale. Test at production line height with sentences containing tone marks over tall consonants.
Enable a Thai analyser in your search engine. Dictionary-based segmentation is what turns Thai search from unusable into usable, because the default whitespace tokeniser produces terms the length of entire clauses. This is a configuration change with a disproportionate effect on how the product feels.
And settle the calendar in the data model rather than in the view. Store Gregorian dates and convert for display through the locale, so there is exactly one place where the 543-year offset is applied and no possibility of a date being stored in one era and read as the other.
What ships broken most often
- Gregorian years shown to Thai users. 2026 rather than 2569 — not a format difference but a wrong year.
-
Missing
lang="th". No dictionary, so no word breaking, so text overflows or breaks mid-word. - Clipped tone marks. Latin line heights cutting the fourth vertical level, which changes the word.
- Whitespace treated as a word boundary. Word counts, truncation and search tokenisation all wrong.
- Search without a Thai analyser. Clause-length terms in the index that never match a query.
- A shared classifier across contexts. อัน used for people, or คน used for files.
- Synthesised italics. Thai has no italic tradition and oblique Thai reads as broken.
The calendar is the item to settle first, because it affects data and not only display. Decide whether stored dates are Gregorian with a presentation-layer conversion — almost always the right answer — and make sure every code path that formats a date for a Thai user goes through the locale rather than through a shared helper written for Western markets.
Install the Laravel-Lang Thai files for framework strings. There is little grammatical complexity to get right compared with the inflected languages, but the messages are already translated in a consistent register, and writing your own leaves you maintaining a second vocabulary alongside the first.
Budget for a native review pass regardless. Every failure mode on this list except the calendar is invisible to a reviewer who does not read Thai — clipped tone marks look like a font quirk, a mid-word break looks like ordinary wrapping, and a wrong classifier looks like text. Coverage figures will report the locale as complete in all of those cases.
Framework strings already translated
Laravel's own validation, auth and pagination strings are maintained in Thai 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 th
php artisan lang:update
Translate your app into Thai today
Import your lang files, translate every key into Thai with one AI click, and publish changes live — no deploy. Set up in 5 minutes.