A specific language and region combination (e.g., en-GB, fr-FR) that the product supports.
A locale names a combination of language and region precise enough to drive how a product reads, formats, and behaves for one audience: en-GB for British English, pt-BR for Brazilian Portuguese, ar-EG for Egyptian Arabic. The slippery part is that people use "locale", "language", and "region" interchangeably, when the product needsNeedUserA user need, pain, desire, or constraintView reference → all three kept apart.
The modern locale tag is standardised by the IETF as BCP 47, a stable name for a series of RFCs. The current syntax lives in RFC 5646, "Tags for Identifying Languages", which obsoleted the earlier RFC 3066 and the 1995 RFC 1766. A tag is hyphen-separated subtags, each adding precision: a language subtag (en), an optional script (Hant for Traditional Han), and an optional region (GB). The individual subtags are catalogued in the IANA Language Subtag Registry, maintained independently so the registry can grow without reopening the RFC.
The format spread because everything adopted it. Windows, Java, C#, JavaScript's Intl, the HTML lang attribute, and the ICU libraries all speak BCP 47. That convergence is why a locale string set in a design file flows untranslated through the whole stack.
A team shipping to Switzerland cannot get away with a single "German" build. They need de-CH, fr-CH, and it-CH. The language subtags pull three translation sets; the shared CH region carries the Swiss franc, the day-month-year date order, and the apostrophe digit grouping (1'000'000). When the same product launches in Germany, de-DE reuses the German strings but switches the currency to euro and the grouping to a full stop. Language and region vary on separate axes, and the locale tag is what lets them vary independently.
en-US and en-GB share a language and disagree on dates, spelling, and the dollar-versus-pound symbol.CH alone cannot tell the product whether to render German, French, or Italian.In the Unified Product Graph, a locale sits in the localisation region and acts as the join point for going global. A product reaches it through Productlocalised inLocalehierarchy. From there a locale draws its translated strings through product_localised_in_localeLocaletranslated viaTranslation Bundlehierarchy and its deeper market-fit work through locale_translated_via_translation_bundleLocaleadapted viaCultural Adaptationhierarchy. Pricing attaches separately, so a locale can carry its own locale_adapted_via_cultural_adaptationRegional PricingLocalisationLocation-based pricingView reference → without entangling currency with language. Keeping the locale as a first-class node, rather than a string buried in a config file, is what lets the graph answer "what does shipping regional_pricingja-JP actually require?" by following its edges.
Type-specific fields on BaseNode
language_codestringISO 639-1 language code (e.g. "en", "de", "ja")
region_codestringISO 3166-1 region code (e.g. "US", "GB", "DE")
is_defaultbooleanWhether this is the default/fallback locale
translation_coveragenumberPercentage of strings translated (0-100)
idstringrequiredUnique identifier (UUID)
typeNodeTyperequiredDiscriminator for the entity type
titlestringrequiredDisplay name
descriptionstringOptional detailed description
statusstringLifecycle status
tagsstring[]Freeform tags for filtering
4 phases — initial: alpha · template: MATURITY
5 edge types connected to this entity.
product_localised_in_localelocale_translated_via_translation_bundlelocale_adapted_via_cultural_adaptationlocale_priced_in_regional_pricinglocale_configured_via_locale_config