How to structure translation keys for dynamic localized strings
Tests ICU MessageFormat and safe interpolation. Outline: one key per sentence with named placeholders; sanitize variables pre-format; use pattern-level plural and select. Red flag: concatenating fragments or injecting raw user input into templates.
WHAT THIS TESTS: This question tests whether you understand that localization is not just swapping words but preserving grammatical structure across languages. Interviewers want to see that you know translators must receive complete sentences with placeholders rather than fragments to assemble, because word order, pluralization, and gender agreement change by locale. They also want to know you treat user-generated content as untrusted data that must be sanitized before interpolation, preventing injection attacks.
A GOOD ANSWER COVERS: First, store each user-facing message as a single translation key containing a complete sentence. Use named placeholders such as {username} and {count} rather than positional ones, because named arguments give translators context and allow them to rearrange clauses for their language. Second, keep all formatting logic out of the component and inside the message pattern. Use ICU MessageFormat complex arguments like plural, select, and selectordinal so the same key handles one message, many messages, or gendered forms without any branching in your code. Third, sanitize or escape dynamic values in application code before passing them into the formatter. If the output targets HTML, either escape the substituted values before they reach the DOM or use a framework that binds text content safely rather than innerHTML. Fourth, separate translation resources from code. Load keys from JSON or YAML files so translators can work on full strings in context without touching source files and without risking broken syntax.
COMMON WRONG ANSWERS: A major red flag is concatenating translated fragments in code, such as t('welcome') plus username plus t('messages'), because this destroys the ability to localize word order and produces broken grammar in many languages. Another is using template literals or string concatenation with raw user input, which opens XSS vectors. Passing unsanitized HTML inside translation values is also dangerous. Hardcoding plural or gender branches in the component rather than the message pattern is wrong because many languages have more than two plural forms, and some have complex gender agreement rules that belong in the translation layer.
LIKELY FOLLOW-UPS: Expect the interviewer to ask how you would handle languages with multiple plural categories like Russian or Arabic. They may also ask what to do when a design requires inline markup such as bold or links inside a translated sentence, or how you would handle gendered pronouns and agreement. Performance of loading large message bundles on the client is another common tangent.
ONE CONCRETE EXAMPLE: Suppose the English source key is welcome_back: Welcome back, {username}. You have {count, plural, one {# new message} other {# new messages}}. The component calls format('welcome_back', { username: escapeHtml(user.name), count: newMessages }). The translator sees the full sentence and can move {username} to the end for their language, or adjust the plural forms to match the six plural categories required by Arabic. The application never concatenates fragments and never injects raw user input into the DOM.
Read the original → unicode-org.github.io
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.