Adding a second language to an app that was built for one is usually a slow, risky refactor. Building for many languages from the first screen costs much less, and for some products it is the only way the product can work at all. This note covers how we approach multilingual architecture at EacTech, from string handling to the per-language content design our games depend on.
Key takeaways
- Retrofitting localization touches nearly every screen, so the cheapest time to prepare is before the first one ships.
- Externalize every user-facing string and use ICU message format for plurals, gender and placeholders.
- Design layouts for longer text, other scripts and right-to-left reading, even before those languages are planned.
- Format dates, numbers and lists with locale-aware APIs, never by hand.
- For word and trivia games, localization is content design per language, not translation.
- Pseudo-localization and native-speaker review catch problems that machine checks and translators working from spreadsheets miss.
Internationalization vs. localization
Two terms get blurred, so it helps to separate them.
Internationalization means building software so it can support any language and region without code changes; localization means producing the actual content, translations and formats for a specific language and region. Internationalization is engineering work done once. Localization is ongoing work done per locale.
Most of the pain teams experience with “localization” is really missing internationalization: strings hard-coded in views, sentences assembled from fragments, layouts that only fit English, and dates formatted with a fixed pattern.
Why retrofitting is expensive
When an app is built for one language, assumptions spread everywhere. Every screen needs its text extracted. Concatenated sentences need rewriting because word order differs across languages. Fixed-width buttons need redesigning. Content stored as plain text needs a language dimension added to its data model. Each change is small; together they touch the whole codebase and require retesting all of it.
The foundations we put in place first
Externalized strings with ICU messages
Every user-facing string lives in a resource file keyed by an identifier, never in the UI code. Flutter, which we use for mobile where appropriate, supports this through its localization tooling and ICU-style messages.
ICU message format matters because languages handle grammar differently. English has two plural forms; many languages have more, and some have several. Placeholders let translators move variables to wherever the grammar requires. A single message can carry those rules:
{count, plural,
=0 {No documents yet}
one {# document}
other {# documents}
}
Translators then supply the plural categories their language needs. The same mechanism handles gender selection and other grammatical choices. The rule we follow: never build a sentence by joining translated pieces in code.
Layouts that tolerate text expansion
Translated text is often longer than English, sometimes much longer, and a short English label can turn into a long compound word. Other scripts may need more vertical space for accents and line height.
So we design components to wrap, grow or truncate gracefully, and we avoid fixed-width buttons and text baked into images. A good habit is to review every new screen with the longest supported language, not the shortest.
Locale-aware formatting
Dates, times, numbers, percentages and lists all vary by locale. The decimal separator, the order of day and month, the first day of the week and the way a list of three items is joined are all regional conventions. We use the platform’s locale-aware formatting APIs for every one of them and never assemble formats manually.
Right-to-left readiness
We have not committed to a right-to-left language yet, but we build as if we might. That means using start and end instead of left and right in layouts, letting the framework mirror directional icons where appropriate, and keeping text direction a property of the locale rather than an assumption of the design. The cost now is small; adding it later means revisiting every screen.
Content localization is not UI translation
Translating buttons and menus is the easy part. For two of our games, the content itself has to be designed separately for each language.
Mystery Word: every language is its own puzzle
Mystery Word, our multilingual word puzzle game, is currently in development. Players connect letters to discover words, which means the game’s core logic depends on language-specific data that cannot be translated from English.
For each language, Mystery Word needs:
- Its own word list and validation dictionary. A level in Spanish is not a translated English level. It is a different set of words built from a different letter pool.
- A defined letter set. Which letters appear on the board, and how often, depends on the language’s alphabet and letter frequency.
- Diacritics rules. Some languages treat an accented character as a separate letter; others treat accents as marks on a base letter. Whether a player must enter the accent, or whether it is folded, is a design decision made per language.
- Word validity rules. Decisions about proper nouns, abbreviations, inflected forms, plurals and offensive words have to be made with someone who knows the language well.
- Casing and sorting rules. Uppercase and lowercase conversion is not universal, and some languages have characters that do not map one-to-one. Locale-aware text handling avoids subtle bugs here.
Themed challenges follow the same principle: a theme has to make sense and be fun in each language, not just exist in translation. Because levels ship with the app for offline-first mobile apps, per-language content packs also influence app size and which languages are bundled versus downloaded.
FootyQuiz: questions that make sense locally
FootyQuiz, our football trivia game, is also in development and is planned with multilingual content. A trivia question is more than a sentence to translate:
- Cultural relevance. A question that is common knowledge in one country may be obscure in another. Question pools need per-language curation, not just translated copies.
- Name transliteration and spelling. Names of people and places can be spelled or transliterated differently across languages. Answer options need consistent, locale-appropriate forms.
- Answer matching. Where answers are compared, rules for accents, spacing and alternate spellings are set per language.
- Fair competition. In multiplayer, players should be matched on equivalent question content. We discuss how language affects ghost matches in designing multiplayer games before you have thousands of players.
Scanzia: UI today, OCR languages later
Scanzia, our document scanner and PDF toolkit, is in development, and its multilingual needs are mostly in the interface: menus, file actions, signing flows and error messages, all handled through externalized strings and locale formatting.
The more interesting work is ahead. OCR is a planned future feature, and text recognition quality depends on the language and script of the document. A user’s interface language and their documents’ language are often different, so OCR language support would need to be its own setting, not inferred from the app locale.
The website follows the same rules
The EacTech website is built with Astro and currently publishes in English. It is structured so that localized routes such as /es/, /de/, /fr/, /it/ and /pt/ can be added later without reorganizing existing pages. Product facts and page copy are kept in structured data rather than scattered across templates, which makes future translation a content task rather than a rebuild.
Process: how strings and content get localized
Pseudo-localization
Before any real translation exists, we run the app with pseudo-localized strings: text that is artificially lengthened and filled with accented characters. It immediately reveals hard-coded strings, clipped labels, broken layouts and fonts missing glyphs. It is one of the cheapest tests available.
Translation workflow
- Every string gets a short context note for translators: where it appears and what it means.
- Screenshots or descriptions accompany strings that are ambiguous out of context.
- New and changed strings are tracked so translators work on deltas, not whole files.
- AI-assisted translation can help produce first drafts where valuable, but it is never the final step.
Native-speaker review
Translations and per-language content are reviewed by native speakers in the context of the running app. For Mystery Word and FootyQuiz, that review covers gameplay content, not only interface text.
Multilingual readiness checklist
| Area | Ready when |
|---|---|
| Strings | No user-facing text in code; all keys have context notes |
| Grammar | Plurals, gender and placeholders use ICU messages |
| Layout | Screens pass review with long text and pseudo-localization |
| Formatting | Dates, numbers and lists use locale-aware APIs |
| Direction | Layouts use start/end; RTL mirroring is possible |
| Content | Data models include a language dimension |
| Games | Per-language word lists, letter sets and question pools are designed, not translated |
| Review | Native speakers check text and content in the app |
Where this leads
Multilingual architecture is one of the principles behind all of EacTech’s mobile products, alongside offline-first design and privacy-aware analytics. It is quiet work that rarely shows up in a feature list, but it decides how far a product can travel.
Mystery Word, FootyQuiz and Scanzia are all in development and are being built with multiple languages in mind from the start. More notes from the studio are in EacTech Build Notes.