HACKER Q&A
📣 withinboredom

Why do you use ids as translation strings?


Earlier this week, my son was unable to purchase a new Minecraft world because (I assume) they didn't expect a non-well-defined locale (en_NL, to be precise). The marketplace is essentially "offer.category.upsell," etc, and so long it fits in exactly 0 buttons.

On everything I've ever worked on that required translations, we always wrote the original text for this exact reason where (for whatever reason), the translation failed. At one place I worked, we had an "en_US" to "en_US" translation set up to quickly change strings without requiring changing the code and breaking other translations. Where I currently work, we have a function like __fixme("not yet translated", "translated") that will use the latter translation if the former isn't translated yet, allowing us to change strings rather easily.

However, after looking around for a bit, I noticed that it has more-or-less become very common to use "opaquish keys" and then provide a translation for every language. This surprises me since AFAIK, every i18n library will default back to the key if it can't find a language to translate to, ergo, opening yourself up to experiencing the app exactly like my son is currently experiencing Minecraft on his Switch.

I'm curious why devs do it using keys vs. the original text? Is there some inherent problem being solved or is it just a personal preference kind of thing?


  👤 Someone Accepted Answer ✓
The original text isn’t guaranteed to work. Two identical strings may need different translations, depending on context.

“Open”, for example, can be a verb or an adjective. In German, the verb may be “öffnen”, “eröffnen”, or “aufschlagen”, depending on context, the adjective “offen”, “frei”, or “eröffnet” (https://www.collinsdictionary.com/dictionary/english-german/... has more options)


👤 toast0
There's a bunch of reasons:

Someone already said it, but using the same English text in two different places often needs different other language text, and that's difficult if the English is your key.

When the English text changes, but the meaning doesn't, you may end up with English instead of the old translation (depends on your system).

If all your text should be ids, you can switch to a ZZ (or something) locale and should see all translation ids (or user data), and if you don't, you know you missed tagging something.

If you do want to fallback to English (or any other language) at runtime (or build time), that's something you can do without needing to have your translation keys be English text. Ideally, I'd want to have a three level check --- do I have the language and locale, if not do I have a default for the language, if not let's go with a default language (unless lang=ZZ as described earlier); but reality sometimes means you need a list of languages that aren't present but should be substituted with something close-ish. And sometimes you end up building a language picker because users may not want to use the system language in your application. i18n is a lot of fun.