Laravel localization in Russian Русский
Everything you need to ship Russian in a Laravel app: the right locale codes,
the exact plural forms trans_choice() expects,
real localized Carbon output and Cyrillic-script considerations.
Every value on this page was generated by running ICU, CLDR and Carbon — not copied from another article.
ISO 639-1
ru
Script / Direction
Cyrillic · LTR
Plural forms (Laravel)
3
Text vs English
Expands
Locale codes
Set the base locale in config/app.php. For regional variants,
Russian commonly uses:
ru_RU, ru_BY, ru_KZ, ru_UA
// config/app.php
'locale' => 'ru',
'fallback_locale' => 'en',
// Or switch at runtime
App::setLocale('ru');
Plural rules: what Russian actually needs
CLDR defines 4 cardinal categories for Russian. The sample numbers below were computed by ICU for this exact locale:
| CLDR category | Numbers that select it |
|---|---|
| one | 1, 21, 31, 41, 51, 61, … |
| few | 2–4, 22–24, 32–34, 42–44, 52–54, 62–64, … |
| many | 0, 5–20, 25–30, 35–40, 45–50, 55–60, … |
| other | 1.5 |
Laravel's trans_choice() maps numbers to
3 pipe-separated
forms for this locale:
| Form index | Numbers that select it |
|---|---|
| 0 | 1, 21, 31, 41, 51, 61, … |
| 1 | 2–4, 22–24, 32–34, 42–44, 52–54, 62–64, … |
| 2 | 0, 5–20, 25–30, 35–40, 45–50, 55–60, … |
// lang/ru/messages.php
'items' => ':count item|:count items'
// Usage
trans_choice('messages.items', $count, ['count' => $count]);
This language uses 3 plural forms. Laravel's built-in trans_choice only resolves two, so for grammatically correct output use an ICU MessageFormat package or handle the extra forms explicitly against the CLDR categories above.
Try any number live in the pluralization tester.
Localized dates with Carbon
Real output for Russian (ru locale),
generated by Carbon for March 21, 2026:
$date = now()->locale('ru');
$date->translatedFormat('l, j F Y');
// "суббота, 21 марта 2026"
$date->isoFormat('LLLL');
// "суббота, 21 марта 2026 г., 14:30"
$date->isoFormat('L');
// "21.03.2026"
$date->subDays(3)->diffForHumans();
// "3 месяца назад"
What to watch out for in Russian
- Six grammatical cases: noun forms change inside sentences, so avoid raw placeholder insertion.
- Plural rules use one/few/many/other categories (1, 2-4, 5+ patterns that repeat by tens).
- Ты/вы formal-informal distinction; three grammatical genders with adjective and past-tense agreement.
- Decimal comma with (non-breaking) space as thousands separator (1 234,56); dates are dd.mm.yyyy.
Cyrillic letters that look exactly like Latin ones
Cyrillic contains a set of characters visually identical to Latin letters in almost every font: а, е, о, р, с, у, х, А, В, Е, К, М, Н, О, Р, С, Т, Х. They are different code points and compare unequal in every string operation, while looking the same on screen to anyone reviewing the text.
This produces bugs that survive indefinitely because they are invisible. A record saved with a Latin о inside a Cyrillic word will not be found by a search using the Cyrillic one, a deduplication routine will treat two identical-looking values as distinct, and a translator who typed one while the source used the other has introduced a mismatch nobody can see by reading.
Flagging mixed-script values
<?php
$hasCyrillic = preg_match('/\p{Cyrillic}/u', $value);
$hasLatin = preg_match('/\p{Latin}/u', $value);
if ($hasCyrillic && $hasLatin) {
// Almost never intentional inside a single word
}
It is also a spoofing vector. Homograph substitution using Cyrillic characters is standard practice for faking domain names and usernames, so fields where visual identity carries trust — display names, organisation names, anything shown as an identity — should be normalised or restricted to a single script rather than accepting mixed input silently.
A related nuisance is ё. It is a distinct letter from е, but Russians routinely write е in its place, so the same word appears both ways in real data. Fold ё to е for search and comparison while preserving whatever the user entered for display.
Three plural forms with a cyclical rule
Russian uses four CLDR categories with a selection rule based on the last digit and last two digits, in the same family as Polish. A two-form translation is wrong for most numbers and the error repeats with every hundred.
| Category | Selected by | Example |
|---|---|---|
| one | 1, 21, 31, 101… | 1 файл |
| few | 2–4, 22–24, 32–34… | 3 файла |
| many | 0, 5–20, 25–30… | 5 файлов |
| other | decimals | 1,5 файла |
The detail that surprises people is that twenty-one takes the one form: 21 файл, singular in shape despite being twenty-one things. Meanwhile eleven takes many, because the teens are excluded from the cycle. Any hand-written $count === 1 check gets both of these wrong.
Four forms in CLDR order
// lang/ru/messages.php
// one|few|many|other
'files' => ':count файл|:count файла|:count файлов|:count файла',
trans_choice('messages.files', $count, ['count' => $count]);
Test with 1, 2, 5, 11, 21 and 1.5. Those six values exercise every branch, including the two exceptions that a translator working from an English source has no reason to anticipate.
Six cases, and the past tense that knows your gender
Russian nouns inflect for six cases across three genders, so a noun has a dozen or more forms and the one required depends on its role in the sentence. As in Polish and Czech, that makes a noun-bearing placeholder unusable across different messages.
| Case | Role | "file" (файл) |
|---|---|---|
| Nominative | subject | файл |
| Genitive | of / negation | файла |
| Dative | to / for | файлу |
| Accusative | direct object | файл |
| Instrumental | by means of | файлом |
| Prepositional | about / in | файле |
Russian past-tense verbs agree with the gender of their subject, which means any sentence telling the user what they did commits to a gender. Ты сохранил addresses a man and Ты сохранила addresses a woman, and there is no neutral alternative in the informal register.
The formal register solves this incidentally. Вы takes plural agreement, and the plural past tense is not gendered — Вы сохранили works for anyone. Since formal address is also the safe default for most software, choosing вы removes the gender problem for free, which is a genuinely useful piece of leverage.
Where informal address is wanted, use impersonal constructions instead: Сохранено (saved) rather than Ты сохранил (you saved). This reads as natural Russian and is what most interfaces do regardless of register.
Formality and names
Russian distinguishes informal ты from formal вы, and the convention leans formal more strongly than in most European languages. Вы is standard for business software, banking, government and anything addressing an adult stranger. Consumer apps aimed at younger users increasingly use ты, but вы is never wrong.
Formal Вы is conventionally capitalised in written correspondence addressed to one person, though lowercase is normal in interface copy. This is a style question rather than a grammatical one, and worth settling in the translation brief so it stays consistent.
Russian names have three parts: given name, patronymic derived from the father's name, and surname. The respectful form of address is given name plus patronymic — Иван Петрович — rather than a title plus surname, and formal correspondence uses it where English would use Mr or Ms with a surname.
A form with only first and last name fields therefore cannot express the standard polite form of address. If your product sends formal correspondence into the Russian market, collecting the patronymic is worth considering; if not, avoid constructing greetings that would conventionally require it.
Surnames are gendered — Иванов for a man and Иванова for a woman — so members of the same family do not share a byte-identical surname. Deduplication and household-grouping logic that assumes they do will misbehave, and gender should not be inferred from the ending.
Layout, sorting and formatting
Russian expands roughly twenty to thirty per cent over English. There are no articles, but case endings, longer stems and a preference for explicit constructions push the total up, and Cyrillic letterforms are slightly wider than Latin at the same point size.
| English | Russian | Growth |
|---|---|---|
| Save | Сохранить | +125% |
| Settings | Настройки | +13% |
| Cancel | Отмена | 0% |
| Sign in | Войти | -29% |
| Search | Поиск | -17% |
| Delete | Удалить | +17% |
Sorting requires a Cyrillic collator. Byte order happens to approximate the Russian alphabet for the basic letters, but it misplaces ё — which belongs after е rather than at the end of the block — and produces nonsense for lists mixing Cyrillic with Latin.
| Russian convention | |
|---|---|
| Thousands | 1 234 567 (non-breaking space) |
| Decimal | 1234,56 |
| Currency | 1 234,56 ₽ (after the amount) |
| Short date | 21.03.2026 |
| Long date | 21 марта 2026 г. |
| First day of week | Monday |
Long dates put the month in the genitive — марта rather than март — and are conventionally followed by г. for год (year). Month names are lowercase. The decimal comma creates the usual numeric-input hazard where floatval() silently truncates the fractional part.
Storage, search and text handled by code
Cyrillic exercises parts of the stack that Latin text never reaches, and the failures usually surface as missing data rather than as visibly broken text, which makes them slow to diagnose.
Encoding first. Cyrillic sits inside the Basic Multilingual Plane, so three-byte encodings technically hold it, but Russian user content routinely carries emoji that do not. Use utf8mb4 for the column, the connection and the table default; MySQL's utf8 will either reject the insert or truncate the field at the first character it cannot represent.
Legacy encodings still appear in imported data. Windows-1251 and KOI8-R were both widely used before UTF-8 became standard, and a CSV exported from an older system will often be in one of them. Text that arrives as sequences of question marks or as unrelated Latin characters is almost always a Windows-1251 file read as UTF-8; detect and convert on import rather than storing the damage.
Search needs three normalisations to behave the way users expect: fold ё to е, apply case folding, and stem. Russian is heavily inflected, so a user searching for a word in its base form will miss every inflected occurrence unless a stemmer is in play. Elasticsearch, Meilisearch and PostgreSQL full-text search all ship Russian stemmers, and enabling the right one changes search from frustrating to usable.
Finally, use multi-byte string functions throughout. Cyrillic characters are two bytes in UTF-8, so strlen() reports roughly double the character count and substr() will split a character in half. Any truncation, padding or length validation written with the single-byte functions will misbehave on Russian text.
What ships broken most often
- Latin homoglyphs inside Cyrillic words. Invisible on screen, unequal in every comparison, and a spoofing vector.
- Two plural forms instead of four. Wrong for most counts; 21 and 11 are the giveaways.
- Gendered past tense with no gender known. Fixed for free by using formal вы.
- Nouns interpolated into sentences. Six cases make a shared placeholder wrong in most contexts.
- ё and е treated as unrelated in search. Real data contains both spellings of the same word.
- Nominative months in long dates. март instead of марта, and the missing г.
- Decimal comma truncating numeric input. The usual silent loss of the fractional part.
The homoglyph problem is the one worth building a check for, because it is the only item here that a Russian reader cannot catch either. Flagging mixed-script values at the point of entry costs a few lines and prevents data that is permanently ambiguous.
Russian is a good proxy for the East Slavic languages. An application handling four plural categories, six cases and gendered past tenses will extend to Ukrainian without structural change, whereas one built on English assumptions needs reworking for both at once.
Install the Laravel-Lang Russian files for framework strings rather than translating validation and authentication messages yourself. They apply the four-form plurals and case agreement consistently across every rule in the framework, and they use the formal register throughout, which is the right default and removes the gendered past tense from several hundred messages at a stroke.
Framework strings already translated
Laravel's own validation, auth and pagination strings are maintained in Russian 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 ru
php artisan lang:update
Translate your app into Russian today
Import your lang files, translate every key into Russian with one AI click, and publish changes live — no deploy. Set up in 5 minutes.