# How localization works

> Understand how localization initializes, selects a locale, and resolves a value.

Understand how localization initializes, selects a locale, and resolves a value.

The [`LocalizationSettings`](/engine/6000.7/script-reference/unity/localization/localizationsettings.md) asset holds the available locales, the startup locale selectors, the content sources, and the [`ResourceDatabase`](/engine/6000.7/script-reference/unity/localization/resourcedatabase.md) that resolves values. The asset ships with the Player and registers itself at startup.

## Initialization

Localization initializes once, the first time something asks for a localized value, or when you call [`InitializeAsync`](/engine/6000.7/script-reference/unity/localization/localizationsettings/initializeasync.md) yourself. Initialization runs three steps in order:

1. Locale discovery: each content source that implements [`ILocaleDiscovery`](/engine/6000.7/script-reference/unity/localization/ilocalediscovery.md) can add locales it finds in its content. For example, a data-file source adds a locale for each table file it finds, so a build can gain a language after release. Refer to [Add a language to a built Player](/engine/6000.7/manual/localization/content-storage-and-loading/add-a-language-to-a-built-player.md).
2. Startup selection: the startup locale selectors run in list order, and localization uses the first selector that returns an enabled locale.
3. Fallback: if no selector returns a locale, localization selects the project locale.

When initialization completes, localization raises [`InitializationCompleted`](/engine/6000.7/script-reference/unity/localization/localizationsettings/initializationcompleted.md), and any selector that needs one-time setup runs at this point.

## How a value resolves

{ /*  Mermaid source kept for the future doc platform; shown as the static image below until mermaid rendering is supported.  */ }

```mermaid
flowchart TD
    ref["LocalizedString / LocalizedAsset<br>(table reference + entry reference)"]
    ref --> db["ResourceDatabase"]
    db --> src["Content source chain<br>resolves the table for the selected locale"]
    src --> entry["Entry lookup by key or ID"]
    entry --> fb{"Value found?"}
    fb -- no --> fallback["Retry with the locale's fallback"]
    fallback --> entry
    fb -- yes --> smart{"Smart string enabled?"}
    smart -- yes --> fmt["Format with Smart Strings<br>(arguments + local variables)"]
    smart -- no --> post
    fmt --> post["Locale post-processing<br>(IPostProcessValueLocale)"]
    post --> value["Value"]

    classDef code fill:#F5F5F5,stroke:#BDBDBD,color:#111;
    class ref,db,src,entry,fallback,fmt,post,value code;
    linkStyle default stroke:#2196F3,stroke-width:1.5px;
```


**How a localized value resolves, from reference to formatted result.:**
![](/api/media?file=/engine/6000.7/media/images/localization-resolve-flow.svg)

A reference such as [`LocalizedString`](/engine/6000.7/script-reference/unity/localization/localizedstring.md) names a table collection and an entry. It resolves a value in the following order:

1. The `ResourceDatabase` asks the content source chain for the collection's table in the selected locale. Refer to [Content sources](/engine/6000.7/manual/localization/content-storage-and-loading/content-sources.md).
2. The table looks up the entry by key or ID.
3. If the entry has no value, the lookup retries with the locale's fallback.
4. If the key has its **Smart string** toggle enabled, the value formats through [Smart Strings](/engine/6000.7/manual/scripting/smart-strings.md), with any arguments and local variables you supplied.
5. If the locale implements [`IPostProcessValueLocale`](/engine/6000.7/script-reference/unity/localization/ipostprocessvaluelocale.md), it post-processes the value. A pseudo-locale can use this hook to transform text for layout testing.

Every step has a synchronous and an asynchronous path. Refer to [Synchronous and asynchronous loading](/engine/6000.7/manual/localization/content-storage-and-loading/synchronous-and-asynchronous-loading.md).

## React to language changes

Localization raises [`LocalizationSettings.SelectedLocaleChanged`](/engine/6000.7/script-reference/unity/localization/localizationsettings/selectedlocalechanged.md) when the language changes. References raise their own events too: a `LocalizedString` raises [`StringChanged`](/engine/6000.7/script-reference/unity/localization/localizedstring/stringchanged.md) with the new value, so UI subscribed to it updates without polling.

## Additional resources

* [Locales](/engine/6000.7/manual/localization/locales.md)
* [Content sources](/engine/6000.7/manual/localization/content-storage-and-loading/content-sources.md)
* [Localize strings](/engine/6000.7/manual/localization/translations/localize-strings.md)
* [Generate dynamic text with Smart Strings](/engine/6000.7/manual/scripting/smart-strings.md)
