DEV Community

Akmal Urunboev
Akmal Urunboev

Posted on Edited on

What breaks when you ship to ten locales at once

I localized a mobile app into ten languages. Most of what I'd read beforehand was about how to translate. Almost none of it was about what goes wrong after, which turned out to be the harder half.

These are the mistakes I actually made.

1. I translated the content and left the chrome in English

This is the one I'd undo first.

The core content — the part users came for — got translated properly. The surrounding interface did not, or did only partly. Settings, error states, the subscription screens, legal copy, empty states.

The result is worse than an English-only app, because it sets an expectation and then breaks it. A user who has been reading comfortably in their own language hits a wall precisely when something has gone wrong or something is being asked of them. The experience doesn't degrade gradually; it fractures at the exact moments that matter most.

The lesson: a locale is either done or it isn't. Partial coverage is not partial credit. If you can't finish a language, ship it later.

2. I shipped locales before I knew anyone wanted them

Adding a language feels like growth. It is cheap to start and expensive forever: every string you ever write afterwards is now ten strings, every feature ships at the speed of your slowest translator, every bug report might be a translation bug.

I added languages because I could reach those speakers, not because I had evidence they were waiting. Some were right. Some were an ongoing tax I'm still paying.

The lesson: treat each locale as a permanent operational commitment, not a one-time content cost. Ask what evidence would justify it, then go find that evidence first.

3. I couldn't review what I couldn't read

Obvious in hindsight. I shipped languages I don't speak, with no process for knowing whether they were any good beyond "the translator seemed competent."

You cannot eyeball your way out of this. You need either a native reviewer who is separate from the translator, or a sampling process, or both — and you need it before launch, because the alternative is finding out from a one-star review written in a language you'll have to machine-translate to read.

The lesson: budget for review as a separate line from translation. They are different jobs and the same person should not do both.

4. I let terminology drift

Several translators, one corpus, no glossary. The same domain term ended up rendered three different ways across the app.

Each individual choice was defensible. Collectively it made the product feel like it had been assembled from parts, and worse, it made the material harder to learn from — the whole point of consistent terminology in educational content is that the learner builds one mental model, not three.

The lesson: the glossary comes before the first word is translated. Retrofitting consistency across a large corpus is enormously more expensive than establishing it.

5. I assumed text length was roughly constant

German and Russian run substantially longer than English. Some languages run shorter. Either way, layouts built around English string lengths break — truncation, wrapping into two lines, buttons growing past their container, labels colliding.

This is not caught by review, because reviewers read text, they don't measure it. It is caught by pseudo-localization — rendering your UI with artificially lengthened strings before you have any real translations — which costs almost nothing and would have saved me a round of layout fixes.

6. I treated RTL as "a language"

Arabic isn't another locale in the list; it's a different layout direction. Mirrored navigation, flipped icons that indicate direction, number and punctuation handling inside mixed text.

Most frameworks handle the basics. The basics are not the problem — the problem is every place someone hardcoded a left margin, every directional icon that shouldn't flip (a play button) sitting next to one that should (a back arrow), and every string that mixes scripts.

The lesson: if RTL is in your plan, put it in early. Adding it after a year of LTR-only development means auditing every layout you've written.

What I'd do differently

Pick two languages. Do them completely — content, interface, store listing, support. Build the glossary, the review process and the pseudo-localization step while the surface area is small enough to hold in your head.

Then add the third.

The instinct is to go wide early because the marginal translation cost looks low. The translation is not the cost. Everything downstream of it is.


I build and operate multilingual mobile applications, shipped across ten languages. More at akmalu.com.

Top comments (3)

Collapse
 
svgicons profile image
Svg/icons •

The RTL icon point is easy to underestimate. Have you considered classifying assets as mirror, invariant, custom RTL, or unknown instead of fixing directionality component by component?

Collapse
 
akmalurunboev profile image
Akmal Urunboev •

That's better than what I described, and I think the fourth bucket is why.

Deciding per component means the decision gets re-made every time the asset is used, by whoever happens to be writing that screen. Classifying the asset means it gets made once, by someone actually thinking about it. But the real value is unknown — without it, anything untriaged silently inherits a default, and silent defaults are exactly how a play button ends up pointing the wrong way in production. With it, you can fail a build on it.

One refinement from doing this across a real icon set: directionality sometimes belongs to the usage rather than the asset. The same arrow mirrors when it means "next" and doesn't when it means "increase". So I'd let a usage site override the asset's classification, but require the override to be explicit rather than inherited.

Where I'd keep it: classification as asset metadata — a manifest entry or a filename convention — with the rendering layer reading it, so no component decides directionality on its own. That was the actual problem.

Thanks for this — I've worked it into a longer piece on RTL that just went up: dev.to/akmalurunboev/right-to-left...

Collapse
 
svgicons profile image
Svg/icons •

Ah, that's a good point about the same arrow being used differently depending on the context. Hadn't thought of that!