Laravel localization in Korean 한국어

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

ISO 639-1

ko

Script / Direction

Hangul · LTR

Plural forms (Laravel)

1

Text vs English

Contracts

Locale codes

Set the base locale in config/app.php. For regional variants, Korean commonly uses: ko_KR

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

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

Plural rules: what Korean actually needs

CLDR defines 1 cardinal category for Korean. 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/ko/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 Korean (ko locale), generated by Carbon for March 21, 2026:

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

$date->translatedFormat('l, j F Y');
// "토요일, 21 3월 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 Korean

Particles change with the preceding syllable

Korean marks the grammatical role of a noun with a particle attached to it. Several of these particles have two forms, and which one applies depends on whether the preceding syllable ends in a consonant — the batchim, or final consonant. This is the single most important thing to understand before putting a placeholder anywhere near Korean text.

Role After a consonant After a vowel
Topic 은 (책은) 는 (파일는 → 파일은*)
Subject 이 (책이) 가 (파일이 → 파일가*)
Object 을 (책을) 를 (파일를 → 파일을*)
And / with 과 (책과) 와 (파일와)
To 으로 (책으로) 로 (파일로)

So a template that appends 를 to a variable produces correct Korean when the value ends in a vowel and incorrect Korean when it ends in a consonant. Roughly half of all values will be wrong, and to a Korean reader the error is as obvious as writing "a apple" in English.

Why the particle cannot be baked into a template

// English: 'Delete :name'
// Korean needs the object particle to match
// the last syllable of the name:
//
//   파일 (ends in vowel)     -> 파일을
//   프로젝트 (ends in vowel)  -> 프로젝트를
//   문서 (ends in vowel)     -> 문서를
//   앨범 (ends in consonant)  -> 앨범을
//
// ':name를 삭제' is wrong for half the values.

The particle can be computed, because Hangul is algorithmically decomposable: a syllable block's final consonant is derivable from its Unicode code point. If you must interpolate nouns, calculate the particle rather than hardcoding it.

Deriving the particle from the last syllable

<?php

function hasBatchim(string $word): bool
{
    $last = mb_substr($word, -1);
    $code = mb_ord($last, 'UTF-8');

    // Hangul syllables occupy U+AC00–U+D7A3
    if ($code < 0xAC00 || $code > 0xD7A3) {
        return false;
    }

    return (($code - 0xAC00) % 28) !== 0;
}

$particle = hasBatchim($name) ? '을' : '를';

That works for native Korean words. It fails for Latin names, numbers and acronyms, where the particle follows the pronunciation rather than the spelling, and pronunciation is not derivable from the characters. The safer approach remains a complete sentence per key, with the variable quoted so no particle attaches to it directly.

Speech levels are the register decision

Korean encodes politeness in verb endings, with several distinct speech levels. Software has settled on two of them, which makes the choice simpler than the full grammatical picture suggests.

Level Ending Used for
합쇼체 (formal) -습니다 / -ㅂ니다 Notices, errors, formal messages
해요체 (polite) -어요 / -아요 Conversational interfaces, consumer apps
해라체 (plain) -다 Headings, labels, documentation
반말 (casual) -어 / -아 Never in software

Most Korean software mixes deliberately: the formal -습니다 for system messages and errors, and the plain declarative or a bare noun for buttons and headings. Buttons are conventionally nouns — 저장 (save), 삭제 (delete), 취소 (cancel) — which avoids the question entirely for short labels, exactly as in Japanese.

Korean also avoids second-person pronouns in interfaces. 당신 (you) is grammatically correct and sounds distant or confrontational in an application; natural Korean omits the subject or uses the person's name with an honorific. A literal translation of "You have 3 messages" that includes 당신 immediately reads as translated text.

Honorific verb forms exist for referring respectfully to the user's own actions, marked with the infix -시-. These appear in customer-facing messages from a service to a user, so a translator will use them in places an English source gives no hint about.

No plurals, but counters everywhere

Korean has no obligatory grammatical plural. CLDR gives it a single category, so trans_choice() takes one form that serves every number. A plural marker 들 exists but is optional and sounds unnatural when a number is already present.

One form for every count

// lang/ko/messages.php
'files' => '파일 :count개',

// 0  -> 파일 0개
// 1  -> 파일 1개
// 42 -> 파일 42개

As in Japanese, the complication moves to counters. Korean requires a classifier between the number and the noun, chosen by what is being counted, so a single generic counting string cannot be reused across contexts.

Counter Used for Example
Generic objects, items 파일 3개
People 사용자 3명
Flat things: pages, images 이미지 3장
Records, cases, transactions 주문 3건
Occurrences, attempts 시도 3번
Machines, vehicles 기기 3대

Korean also has two number systems — native Korean and Sino-Korean — and which one is spoken depends on the counter. This does not change the written digits, so it rarely affects an interface, but it matters for any voice output built on the same strings.

Hangul, spacing and line breaking

Hangul is an alphabet arranged into syllable blocks: each block encodes two or three letters and occupies one square cell. This makes Korean visually dense like Chinese or Japanese while being alphabetic underneath, which has consequences for both layout and text processing.

Korean uses spaces between words, unlike Japanese and Chinese, and the spacing rules (띄어쓰기) are genuinely difficult — even native speakers disagree on some cases. Do not attempt to normalise or insert spacing programmatically; treat the translator's spacing as authoritative.

Line breaking has a subtlety worth setting explicitly. Because Korean is syllabic, browsers may break a line between any two syllable blocks rather than at word boundaries, which is technically permitted and looks careless. Declaring word-based breaking produces noticeably better typography.

Prefer word boundaries for Korean

<p lang="ko" class="[word-break:keep-all] [overflow-wrap:break-word]">
    사용자 계정 설정이 저장되었습니다.
</p>

/* keep-all stops the browser breaking mid-word
   between syllable blocks; overflow-wrap still
   rescues genuinely over-long tokens. */

Korean text runs shorter than English in character count but each character is full-width, so rendered width lands close to the English original. Overflow is rare. As with Japanese, dense glyphs need more line height and suffer badly at small font sizes.

Text entry goes through an input method that composes syllable blocks as the user types. Any JavaScript reacting to every keystroke will fire on incomplete blocks, so live search and validation must respect compositionstart and compositionend rather than the raw input event.

Names, dates and formatting

Korean names are written family name first, with no space in the traditional form: 김민준 has the surname 김. Names are typically three syllables, and a form designed around a long given name and a separate surname field can feel oddly shaped. Store the parts separately and let the locale decide display order.

Surnames are drawn from a small pool — Kim, Lee and Park together account for close to half the population — so any logic treating a surname as distinguishing will collide constantly. Deduplication, search ranking and display disambiguation all need to account for that.

Korean convention
Date 2026년 3월 21일
Numeric date 2026. 3. 21.
Weekday 토요일 (Saturday)
Thousands 1,234,567
Decimal 1234.56
Currency ₩1,234 (no decimals)
First day of week Sunday

Dates run largest unit first with the year, month and day markers 년, 월, 일. Numbers follow English conventions, so there is no decimal-comma hazard. The won has no subunit in circulation, so amounts carry no decimal places — formatting them with two is an immediate sign of code written for dollars, and amounts are large enough that currency fields need room for more digits than a euro design assumes.

Korean addresses have been officially road-based since 2014, but the older lot-based system is still in common use, and address forms are ordered largest unit first: province, city, district, street, building. An address form laid out in Western order will confuse users even when every field is translated.

Getting Korean into the application

Korean exercises input handling, typography and string architecture at once, and the wiring around the translations causes as many visible defects as the translations themselves.

Start with the input method, because it affects every text field in the product. Any behaviour bound to keystrokes — live search, character counters, inline validation, autosave — must wait for the composition to finish. A counter that counts partial syllable blocks reports wrong numbers, and validation that runs mid-composition rejects text the user is still in the middle of typing. Bind to compositionend and treat input as authoritative only when no composition is active.

Storage needs utf8mb4 throughout. Hangul syllables sit inside the Basic Multilingual Plane and are safe in three-byte encodings, but Korean text routinely carries emoji and occasionally rare Hanja that are not, and MySQL's utf8 will either reject the insert or truncate the field at the offending character.

Sorting requires a locale-aware collator. Korean orders by the alphabet underlying the syllable blocks rather than by code point, and while the two happen to coincide for much of the range, mixed text containing Hanja or Latin will not sort acceptably without it. Search should also normalise fullwidth Latin characters, which Korean keyboards can produce, using NFKC.

Finally, write the string architecture for particles from the beginning. Deciding later that variables must be quoted and messages must be complete means revisiting every interpolated string in the product, and it is the one Korean problem that cannot be fixed by retranslation.

What ships broken most often

The particle problem is the one that distinguishes competent Korean localisation from the rest. It cannot be solved by better translation, only by string architecture: complete messages per key, and variables quoted so no particle attaches to them. Teams that get this right ship Korean that reads as written rather than as assembled.

Install the Laravel-Lang Korean files for framework strings rather than translating validation and authentication messages yourself. They already apply the correct speech level consistently and handle particles and counters across every rule in the framework, which is a considerable amount of detail to reproduce by hand.

Korea also has an unusually demanding audience for software quality. English proficiency is lower than in northern Europe, so untranslated strings genuinely block users rather than merely irritating them, and domestic products set a high bar for polish. A partially translated Korean interface reads worse there than the equivalent gap would in the Netherlands or Scandinavia.

Framework strings already translated

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

Translate your app into Korean today

Import your lang files, translate every key into Korean 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