Laravel localization in Turkish Türkçe

Everything you need to ship Turkish in a Laravel app: the right locale codes, the exact plural forms trans_choice() expects, real localized Carbon output and Latin-script considerations. Every value on this page was generated by running ICU, CLDR and Carbon — not copied from another article.

ISO 639-1

tr

Script / Direction

Latin · LTR

Plural forms (Laravel)

1

Text vs English

Similar

Locale codes

Set the base locale in config/app.php. For regional variants, Turkish commonly uses: tr_TR, tr_CY

// config/app.php
'locale' => 'tr',
'fallback_locale' => 'en',

// Or switch at runtime
App::setLocale('tr');

Plural rules: what Turkish actually needs

CLDR defines 2 cardinal categories for Turkish. The sample numbers below were computed by ICU for this exact locale:

CLDR category Numbers that select it
one 1
other 0, 2–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/tr/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 Turkish (tr locale), generated by Carbon for March 21, 2026:

$date = now()->locale('tr');

$date->translatedFormat('l, j F Y');
// "Cumartesi, 21 Mart 2026"

$date->isoFormat('LLLL');
// "Cumartesi, 21 Mart 2026 14:30"

$date->isoFormat('L');
// "21.03.2026"

$date->subDays(3)->diffForHumans();
// "3 ay önce"

What to watch out for in Turkish

The dotted and dotless i will break your code

Turkish has four i-letters, not two. Alongside the familiar dotted pair it has a dotless ı and its capital I, and the case mappings cross over in a way no other language does.

Lowercase Uppercase Letter
i İ (dotted capital) dotted i
ı I (dotless capital) dotless i

So uppercasing i in Turkish gives İ, not I, and lowercasing I gives ı, not i. This is the single most notorious internationalisation bug in software, because it silently breaks code that has nothing to do with display.

The classic Turkish-locale failure

<?php

// With a Turkish locale active, a locale-aware
// uppercase turns 'title' into 'TİTLE'
setlocale(LC_ALL, 'tr_TR');

// Any code doing case-insensitive comparison by
// uppercasing then matching against 'TITLE' now fails.
// Classic victims: header names, file extensions,
// config keys, HTML tag names, 'ID' vs 'id'.

The rule is to keep locale out of machine-facing comparisons entirely. Use locale-invariant case folding for identifiers, protocol tokens, file extensions and config keys, and reserve locale-aware case conversion strictly for text being shown to a person. In PHP that means strtolower() for identifiers and mb_convert_case() with an explicit locale for display.

The same applies in the database: a case-insensitive collation set to Turkish will match i and ı differently from every other locale, which affects unique constraints on usernames and email addresses. Store and compare those with a locale-invariant collation.

This bug does not require Turkish users. It requires a Turkish locale being active in the process, which can happen from a server setting, a request header or a library call, and it then breaks the application for everyone.

Vowel harmony and suffixes with four forms

Turkish is agglutinative: grammatical relationships are expressed by suffixes attached to the word, and suffixes stack. Where English uses prepositions and separate words, Turkish builds a single long token.

The suffixes are not fixed. Turkish vowel harmony means the vowel in a suffix must match the vowels of the stem, and many suffixes therefore have two or four written variants. Consonants can change as well, so the same grammatical ending looks different depending on the word it attaches to.

Meaning Example Suffix variant
in the file dosyada -da
in the house evde -de
in the book kitapta -ta (consonant change)
in the fruit meyvede -de

This makes placeholders holding nouns fundamentally unsafe, exactly as in Hungarian and Finnish. A template appending a suffix to a variable will produce the wrong form for most values, and the correct variant depends on the vowels and final consonant of a word chosen at runtime.

A template that cannot be made correct

// English: 'Saved in :folder'
// Turkish needs the locative suffix to harmonise:
//
//   Belgeler -> Belgelerde
//   Resimler -> Resimlerde
//   Kitap    -> Kitapta
//
// -da, -de, -ta and -te are all the same suffix.

The workable pattern is to quote the variable and attach the suffix to a fixed noun instead: „Resimler” klasörüne kaydedildi. The grammar now lands on klasör (folder), which you control, and the variable sits untouched in quotation marks.

One plural form, and none after numbers

CLDR gives Turkish two plural categories, so trans_choice() takes a two-part string. But there is a rule that matters more than the category count: Turkish does not use the plural suffix after a number. Three files is üç dosya, not üç dosyalar — the numeral already conveys plurality.

A numeral suppresses the plural suffix

// lang/tr/messages.php
'files' => ':count dosya|:count dosya',

// 0  -> 0 dosya
// 1  -> 1 dosya
// 42 -> 42 dosya
//
// ':count dosyalar' is wrong for every number.

The plural suffix -ler or -lar does exist and is used when no number is present — dosyalar (the files) — so both forms occur in an interface. A translator working from an English source with singular and plural forms will often supply the suffixed noun for the second, producing text that is wrong wherever a count appears.

Turkish also has no grammatical gender and no gendered pronouns: o covers he, she and it. That removes an entire class of agreement problems and makes gender-neutral copy the default rather than something to engineer around.

Turkish also lacks articles entirely, so there is no equivalent of the a/an or der/die/das problem that defeats templates elsewhere. Between that and the absence of gender, the only structural obstacle to interpolation is the suffix harmony described above — which is unfortunately sufficient on its own.

Sen or siz, and how Turkish addresses people

Turkish distinguishes informal sen from formal siz, with siz also serving as the ordinary plural. Software convention leans formal: banking, government and business software use siz, and consumer products increasingly use sen but with less uniformity than in Scandinavia.

English Informal (sen) Formal (siz)
Your account hesabın hesabınız
Do you want to continue? Devam etmek istiyor musun? Devam etmek istiyor musunuz?
Welcome Hoş geldin Hoş geldiniz

Note that possession is a suffix rather than a separate word — hesabınız is account-your, one token — so switching register changes the shape of nouns, not only pronouns. This is another reason the choice cannot be swapped late.

Turkish interfaces commonly use the verbal noun for buttons — Kaydet, İptal, Sil — which sidesteps the register question for short labels, as in most languages with a formality distinction.

Layout, sorting and formatting

Turkish expands roughly twenty to thirty per cent over English, and agglutination means individual words can become very long. A stacked chain of suffixes produces a single token with no space to wrap at, so plan for German-like overflow behaviour even though the languages are unrelated.

English Turkish Growth
Save Kaydet +50%
Settings Ayarlar -13%
Cancel İptal -17%
Sign in Giriş yap +13%
Your account settings Hesap ayarlarınız suffixed

Sorting needs a Turkish collator. The alphabet includes ç, ğ, ı, ö, ş and ü, each sorting immediately after its base letter, and dotless ı sorts before dotted i — an order no generic Unicode collation produces.

Turkish collation

<?php

$collator = new Collator('tr_TR');
$collator->sort($words);

// Correct order: ... g, ğ, h, ı, i, j ...
// A generic collator places ı and i the other way round.
Turkish convention
Thousands 1.234.567
Decimal 1234,56
Currency 1.234,56 ₺
Short date 21.03.2026
Long date 21 Mart 2026
First day of week Monday

Month names are capitalised in Turkish, unlike most European languages. The decimal comma creates the usual numeric-input hazard where floatval() silently discards the fractional part, and the lira is subject to enough inflation that amounts run long — currency fields need room for more digits than a euro design assumes.

Auditing for the locale-sensitive case bug

The dotted-i problem is worth treating as a codebase audit rather than as a Turkish translation task, because it is triggered by a locale being active in the process and affects every user once it is. The work is finding the places where case conversion is used as logic rather than as presentation.

Grep for case functions and classify each call site. Anything comparing a header name, a file extension, a config key, a database column, an enum value, a route name, an HTML tag or a protocol token is machine-facing and must use locale-invariant folding. Anything producing text a person will read is display and may be locale-aware.

In PHP the distinction is not enforced by the function names, which is what makes this easy to get wrong. strtolower() is byte-based and locale-invariant in modern versions, so it is safe for identifiers; mb_convert_case() and anything honouring setlocale() is not. Laravel's Str::lower() uses the multibyte functions, so it belongs in display code rather than in comparisons.

Databases need the same review. A case-insensitive collation configured for Turkish will fold I onto ı rather than i, so a unique constraint on usernames or email addresses behaves differently from every other locale. Store identifiers with a locale-invariant collation and keep the Turkish collation for user-visible sorting.

A regression test is worth writing once. Set the process locale to Turkish, run the comparison paths you rely on, and assert they still match. It takes minutes and it pins down a class of bug that is otherwise discovered only when a server configuration changes.

What ships broken most often

The i-bug deserves its reputation. It is the one entry on this list that damages the application for users who have nothing to do with Turkish, it is triggered by configuration rather than by content, and it produces failures — a header not matching, a file extension not recognised — that look nothing like a localisation problem. Audit for locale-aware case conversion in non-display code before it bites.

Install the Laravel-Lang Turkish files for framework strings. They handle the suffix harmony and the numeral rule consistently across every validation message, which is a considerable amount of detail to reproduce by hand.

Turkish also shares the agglutinative structure of Hungarian and Finnish, so the string architecture that works for one works for all three. If your messages are already written as complete keys with quoted variables, Turkish costs little beyond the case audit; if they are assembled from fragments, Turkish will expose that in the same way those languages do, and the fix is the same restructuring.

One further formatting note: Turkey moved to permanent daylight saving time in 2016 and no longer changes its clocks. Scheduling and reminder features that assume a European transition schedule will drift for Turkish users twice a year, and the failure is subtle enough to go unreported for a long time.

Framework strings already translated

Laravel's own validation, auth and pagination strings are maintained in Turkish 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 tr
php artisan lang:update

Translate your app into Turkish today

Import your lang files, translate every key into Turkish with one AI click, and publish changes live — no deploy. Set up in 5 minutes.

We use cookies to improve your experience and analyze site traffic. Cookie Policy

Cookie Preferences

Essential

Required for the site to work

Analytics

Help us improve the site

Marketing

Personalized ads and content