← Studio Log
D. 기술 신뢰 (Uy tín)다국어국제화로케일앱 개발베트남 시장

Locale Design: Vietnamese, Korean, English in One App

Locale Design: Vietnamese, Korean, English in One App
by Yeowubie

Why Shipping a Translation File Is Not the End

Treating multilingual support as string replacement pushes problems downstream. The sentences on screen are only one of many values a locale decides. Date format, number separators, name order, address input order, sort rules, and notification timing all branch alongside them. The translation file is simply the most visible layer.

Most real incidents happen outside the sentences. Vietnamese users write dates as day, month, year. Korean users start with the year. English speakers read the same date in yet another order. If the server builds the date string in one fixed order and sends it down, the client has no room to intervene. When the server sends an absolute timestamp and leaves formatting to the client, adding a locale later does not force changes to server code. Deciding where that boundary sits is the first design call.

Sorting is easy to overlook. When a product says it sorts names alphabetically, that order differs by language. Vietnamese has its own rules for characters carrying tone and diacritic marks, and Korean follows the consonant order of its alphabet. Leaving this to the database default collation produces a list that looks randomly shuffled to the user. Nobody complains while the dataset is small. The reports arrive once the data piles up.

Search is harder still. Vietnamese users frequently type without diacritics. Comparing the stored form directly means users fail to find entries that plainly exist. Building a secondary index with diacritics stripped at write time is the safer route. In Korean, some users expect to search by initial consonants. These expectations vary by language and never surface in a translation file.

Yeowubie Interaction works across Korea and Vietnam, building its own products while developing client products at the same time. With that setup, multilingual work is closer to a baseline condition than an option. onSpots, an attendance management service, was built as a multilingual service that is not tied to a single country. Langtori, a matching and mapping tool that connects people learning Korean with people teaching it, supports Korean, Vietnamese, and English locales with Vietnamese as its primary focus. In both products, the work outside the translation files consumed more time than the files themselves.

The short version is that internationalization is a data modeling job, not a string job. Deciding which values are stored in raw form and which are rendered at display time comes first. Reversing that order means reopening several parts of the codebase every time a language is added.

Treat Language, Region, Currency, and Date as Separate Fields

Bundling locale into a single value guarantees a later split. Language, region, currency, time zone, and date format vary independently. A Korean living in Vietnam may want a Korean interface while using Vietnamese time and Vietnamese dong. A structure that cannot express that combination forces the user to give something up.

If the user profile carries exactly one language field, that combination is blocked from the start. At minimum, store display language and region as separate fields, and keep time zone in its own field. Currency usually has to follow the currency of the transaction rather than a user preference, so it belongs to the payment domain. Splitting these up front means later region rules can be added without touching the existing fields.

Money display needs its own attention. Vietnamese dong effectively does not use decimal units and carries large digit counts. Korean won has no decimal unit either. United States dollars use two decimal places. Hard coding decimal precision into application code adds a conditional branch for every new currency. A more durable approach stores amounts as integers in the smallest unit, keeps the currency code traveling with the amount, and reads display precision from currency metadata. Grouping separators also differ by region. In some regions the roles of the period and comma are reversed, so assembling number strings by hand invites defects.

For time, keep storage and display firmly apart. Store absolute timestamps with time zone information in the database, then convert to the user time zone for display. Korea and Vietnam sit two hours apart, so in features where a timestamp decides an outcome, such as attendance or a submission deadline, that gap turns into a dispute quickly. Which time zone defines the boundary of a day is also a policy decision. Unless the document states whether it means midnight in the user time zone or midnight in the operating time zone, every implementer will resolve it differently.

Decide early how values get inserted into sentences. Cutting a sentence into fragments and concatenating them collapses in languages with different word order. Korean places the predicate at the end, and Vietnamese places modifiers after the noun. The unit of translation therefore has to be a full sentence containing placeholders. Most widely used internationalization libraries support this, but the exact syntax differs between them, so read the actual documentation before adoption and settle on one team convention.

Plural handling also varies. English distinguishes singular from plural, while Korean and Vietnamese do not enforce that distinction grammatically. Hard coding a two way branch based on English produces awkward output in the other languages. Declaring plural rules per language inside the translation resources, with the code passing only the count, is the safer structure.

What Vietnamese and Korean Do to Your Layout

The same message runs to different lengths in different languages. Vietnamese needs more vertical room because of its tone marks, Korean compresses tightly, and English lands somewhere between. The difference shows immediately wherever width is fixed, in buttons, tabs, and card titles. Layouts have to be validated against the longest language.

Vietnamese tone and diacritic marks sit both above and below the base character. Tight line height clips the upper marks or makes them collide with the line above. Spacing that looks fine in Korean and English while breaking only in Vietnamese usually traces back to this. Font selection needs the same check: confirm the typeface actually covers Vietnamese extended characters. If it does not, the browser or operating system substitutes another face, and letter shapes end up mixed inside a single sentence.

Korean brings a separate line breaking problem. Under default web behavior, Korean breaks in the middle of a word and pushes the remainder to the next line. A two syllable word split across two lines reads as wrong immediately. It looks cosmetic, but it is really a matter of readability and trust. The style layer has to declare that line breaking happens at word boundaries, and in places where the break itself carries meaning, such as headlines, it is better to place the line divisions deliberately instead of leaving them to automatic wrapping. Unless a developer already knows this, nobody will flag it, because to a reviewer who does not read Korean the screen looks normal.

Absorb length differences through design rather than through translation. Trimming a translation to force a button label onto one line blurs the meaning. Instead, let the button grow to two lines, or set a minimum height and let the content push it. Table style screens are especially fragile. A table with fixed column widths fits one language and either clips or leaves gaps in the others. Converting tables into card lists on narrow screens also works in favor of multilingual layouts.

Fix the verification method too. Every time a screen is built, look at the actually rendered result in all three languages, on both desktop and mobile. Passing a type check is not a layout check. Another useful habit is testing with the longest available string. If translations are not ready, use a padded dummy string to probe the width first.

Keep truncation as a last resort. A truncated sentence is information that has gone missing, and the user cannot tell what was removed. For values that matter to the user, such as names, addresses, and shop titles, truncation is a real problem. Deciding at the screen design stage which values may be truncated and which must always display in full prevents arguments in the middle of implementation.

Choosing a Default Language and Fallback Rules

Without a settled default and fallback chain, screens end up empty or expose raw translation keys. Three things need a decision: what a first time visitor sees, which language the system falls back to when a translation is missing, and how long an explicit user choice is honored. All three are policy, not code.

For the first screen, consult browser or device settings without following them blindly. Devices sold in Vietnam are often set to English, and some Korean users run an English operating system. Put the device setting, the access region, and the product's primary market side by side and set an order of precedence. Langtori supports three languages but keeps Vietnamese as its focus, so ambiguous cases lean Vietnamese. Decisions like this differ by product, and the reasoning belongs in a document so the argument does not restart later.

When a user changes the language themselves, that is the strongest signal available. On later visits, prefer the user choice regardless of device settings. Store it on the account for signed in users and in browser storage for everyone else. The common bug appears at sign in, when the stored account value overwrites the current selection and the interface switches languages without warning. Decide in advance which side wins, and handle it in one place.

Build fallback as a chain. When a region specific variant is missing, fall back to the parent language, and when that is missing too, fall back to one designated base language. The base language must be the one managed so that no translation is ever missing. Treating all three languages as perfectly equal usually ends with none of them complete. If even the base language lacks a key, the raw key string reaches the screen, so a build step that checks for missing keys and fails the build is worth adding.

Fallback applies beyond text. Banners with text baked into the image, terms documents that differ by language, and language specific support channels follow the same rule. A Vietnamese screen that links to Korean terms loses the user's trust at that exact moment. For documents with legal effect, the product also has to state which language version governs. This part warrants separate confirmation depending on the nature of the service.

Settle the address structure early as well. Putting the language in the path, splitting by subdomain, or keeping one address and deciding by header leads to different search visibility and different sharing behavior. If one address shows different languages to different visitors, search engines struggle to decide which language to index, and someone receiving a shared link may see a different language than the sender did. Giving each language its own address and declaring the links between them is easier to operate.

Multilingual Work Continues into Content Operations

Multilingual work does not end at release. Announcements, product descriptions, help pages, and push notifications keep appearing after launch. Without a decision on who fills all three languages, in what order, and what appears when one language is still empty, the versions drift apart over time. The operating rules matter as much as the code.

Start with the content model. One item with per language bodies attached beneath it lets translation status be tracked per item. Creating a separate item per language makes it impossible to tell which one is the source and which translations went stale when the source changed. Adding a status field to each language body, distinguishing draft, in review, and published, prevents unfinished translations from leaking to users.

For translation itself, machine drafts followed by human editing is the practical route. The places that need a human are predictable. Product specific terminology, legal wording, and sentences that prompt user action all need human review. Maintaining a separate glossary prevents the same concept from being translated as different words on different screens. The glossary serves as material for translators and simultaneously as an internal agreement document.

Handle notifications separately. Read the user's language setting at send time to select the body, and format timestamps in the user's time zone. A notification composed early and parked in a queue goes out in the old language if the user switched in the meantime. Resolving the language immediately before sending is safer. Send timing should account for region too. Nine in the morning in Korea is seven in the morning in Vietnam.

Search visibility is an operations item as well. Manage titles and summaries separately per language, and do not carry a phrasing that works in one language straight into another. Vietnamese and Korean search queries take different shapes even on the same topic. Rewrite based on what speakers of that language actually type, not on the translated title. This work belongs to content operations rather than engineering, and without a named owner nobody does it.

The last piece is a review cadence. Roughly once a quarter, put the three language screens side by side and compare. The mismatches surface: old guidance that survives in one language only, a new feature description missing from one language, contact channels that differ between languages. In a multilingual product, quality is decided in reviews like this rather than in the initial build. Before deciding to add a language, calculate the cost of maintaining the languages already added.