A single translatable string in the product, its key, source text, and translations across locales.
A translation key is the stable identifier that maps a piece of interface text to its translated string, so code refers to onboarding.welcome.title and the locale decides what those words actually are. The key never changes when the language does, and that constancy is the whole point.
The key emerged from a single discipline of internationalisation: get the words out of the code. The numeronym i18n was coined at Digital Equipment Corporation in the 1980s, and the practice it named centres on externalising every user-facing string into a resource file addressed by a key. A hardcoded label cannot be translated without editing the source; a keyed label can be translated by anyone with the resource file, in any number of languages, without touching the code that displays it.
The keys grew structure as products grew. Flat lists gave way to dotted, namespaced keys (checkout.button.confirm) that mirror the screen hierarchy and keep collisions out. The harder problem was grammar. Different languages have different plural rules, so a naive "1 item / N items" split breaks the moment you reach a language with more than two plural forms. The ICU MessageFormat, backed by the CLDR plural rules, answered this by letting one key hold every variantVariantGrowthA variant in an A/B testView reference → inline: English carries one and other, while Ukrainian needsNeedUserA user need, pain, desire, or constraintView reference → one, few, many, and other. The plural logic lives in the translated message, so the application code stays a single key lookup.
A developer writes t('cart.summary', { count }) instead of the literal "3 items in your cart". The key cart.summary resolves against the active locale. In English the message reads {count, plural, one {# item} other {# items}}; in Polish the same key carries four branches, because Polish distinguishes 1, 2 to 4, and 5-plus. The developer never learns Polish plural rules. The translator handles them inside the key's value, and the count variable is interpolated at render time. Change the displayed wording and only the resource file moves, never a recompile.
In the Unified Product Graph, a translation key is the atom of localisation. It belongs to a bundle through Translation BundlecontainsTranslation Keyhierarchy, which makes the bundle the parent and the key the leaf. That containment matters because it lets the graph reason about coverage: a bundle missing a key that its siblings hold is a queryable gap, the structural signal that one locale has fallen behind. Keys stay locale-neutral by design, so the same translation_bundle_contains_translation_keyonboarding.welcome.title appears once per bundle and the graph can trace exactly which locales have translated it.
Type-specific fields on BaseNode
key_pathstringDot-separated key path (e.g. "onboarding.welcome.title")
source_textstringOriginal source-language text
context_hintstringContextual hint for translators
max_lengthnumberMaximum character length for the translated string
idstringrequiredUnique identifier (UUID)
typeNodeTyperequiredDiscriminator for the entity type
titlestringrequiredDisplay name
descriptionstringOptional detailed description
statusstringLifecycle status
tagsstring[]Freeform tags for filtering
1 edge type connected to this entity.
translation_bundle_contains_translation_key