Skip to content

Add a New Locale

Adding a new locale involves collecting realistic data (names, cities, streets) and formatting rules for a specific country or region. Unlike adding a new resource type, this is primarily a data collection task.

A complete locale implementation requires several files organized into directories representing the locale (e.g., fr_fr), language (e.g., fr), and country (e.g., fr).

Note: All directory and file names use lowercase (e.g., fr_fr, en_us) for cross-platform consistency.

Path: typespec/resources/locale/{locale}/ (e.g., locale/fr_fr/)

FileDescriptionExample
given_male_names.txtCommon male first namesJean, Pierre, Lucas
given_female_names.txtCommon female first namesMarie, Léa, Camille
family_names.txtCommon surnamesMartin, Bernard, Dubois
cities.txtMajor cities in this regionParis, Lyon, Marseille
streets.txtCommon street namesRue de la Paix, Avenue Victor Hugo
zipcodes.txtExamples of valid postal codes75001, 69002
name_format.txtHow names are ordered{given_name} {family_name}

Path: typespec/resources/lang/{language}/ (e.g., lang/fr/)

FileDescriptionExample
nouns.txtCommon nouns in this languagelivre, table, chaise
adjectives.txtCommon adjectivesbeau, grand, petit
verbs.txtCommon verbsmanger, dormir, aller
months.txtMonth names in this languagejanvier, février, mars
weekdays.txtWeekday names in this languagelundi, mardi, mercredi

Path: typespec/resources/country/{country}/ (e.g., country/fr/)

FileDescriptionExample
address_format.txtHow addresses are ordered{street}\n{zip} {city}
street_format.txtHow street numbers/names combine{number} {street}
phone_number_patterns.txtPatterns for valid phones0# ## ## ## ##
timezones.txtValid IANA timezone namesEurope/Paris

Localized data is organized at three levels depending on how specific the data is:

Use this for data that varies by both language and country (e.g., en_us vs en_gb). This is where most names and cities belong.

Terminal window
mkdir -p typespec/resources/locale/fr_fr

Use this for data that is the same for all countries speaking that language (e.g., common nouns, adjectives, months, weekdays).

Terminal window
mkdir -p typespec/resources/lang/fr

Use this for data that is specific to a country but independent of the language (e.g., phone formats, timezones, address formats).

Terminal window
mkdir -p typespec/resources/country/fr

Note: Use lowercase for all directory names (fr_fr, not fr_FR or FR_fr).

Each .txt file must follow these rules:

  • Encoding: Must be UTF-8 without BOM.
  • Format: One entry per line.
  • Cleaning: No empty lines, no leading/trailing whitespace.
  • Uniqueness: Avoid duplicate entries within a file.

Example locale/fr_fr/cities.txt:

Paris
Marseille
Lyon
Toulouse
Nice

Some files use placeholders that are replaced during data generation.

Used in address_format.txt. Common placeholders:

  • {street_address}: The combined street number and name.
  • {locality}: Usually the city.
  • {region}: State, province, or department.
  • {postal_code}: The zip or postal code.
  • {country}: The full country name.

Used in phone_number_patterns.txt. Use # for a random digit:

  • Example: (###) ###-####
  • Example: +33 # ## ## ## ##

Run the code generation to embed the new data into the SDKs:

Terminal window
cd pseudata-poc
task generate

Verify that the new locale appears in:

  1. Atomic modules generated in sdks/{language}/resources/locale/fr_fr/data.{ext}
  2. Bundles updated to include the new locale (check resources/bundles/world.{ext})
  3. AVAILABLE_LOCALES list in each SDK (e.g., sdks/go/resources.go)
  4. Regional bundles automatically include the locale if it matches their geography

After adding a locale, add a few test cases to the Testing Guide to ensure it’s working correctly across all languages.

Example fixture for French locale:

{
"name": "city_fr_fr",
"worldSeed": 42,
"index": 0,
"locale": "fr_fr",
"expected": "Paris"
}

See the Testing Guide for details on how to run and update these tests.