# Smart Localization Suite

Extends localization capabilities with advanced language management and production features.

{% embed url="<https://assetstore.unity.com/packages/tools/localization/smart-localization-suite-335116>" %}

{% tabs %}
{% tab title="Overview" %}
Smart Localization Suite is a production-ready, key-based localization system for Unity, designed for scalable projects and professional pipelines.

Unlike the Lite version, the Suite edition is built around centralized string tables (`LocalizationTable`) and key-driven components (`LocalizedTMPKeyed`). Text is no longer stored per component. Instead, all translations are managed in a single authoritative data source.

The Suite introduces:

* Global key-based architecture
* Centralized `LocalizationTable` asset
* Automated migration from Lite
* Integrated multi-provider translation system
* Secure API key isolation (Editor-only)
* Build-time secret protection
* Quota management and diagnostics
* Automatic setup and validation tools

The system separates runtime data from editor secrets and enforces production-safe workflows through pre-build validation mechanisms.

Smart Localization Suite is designed for teams, pipelines, and shipped products—not prototypes.

<figure><img src="/files/0kMf6D9dCxivhAPSApe5" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Installation" %}
After importing the package, open:

**Project Settings → Smart Localization**

On first access, the system automatically creates:

* A runtime `LocalizationSettings` asset
* An Editor-only `EditorLocalizationSettings` asset (under an `Editor/` folder)

The runtime asset contains language configuration and behavioral settings.

The Editor asset stores provider configuration and secret keys. This asset is validated during build to ensure it is never placed in a runtime-accessible folder.

If no `LocalizationTable` exists in the project, use the Auto Setup tool to create one automatically.
{% endtab %}

{% tab title="Quick Start" %}

1. Open **Project Settings → Smart Localization**
2. Configure supported languages
3. Run the **Auto Setup Tool**
4. Create or verify the `LocalizationTable` asset
5. Add `LocalizedTMPKeyed` to any TextMeshPro object
6. Assign a string key
7. Define `sourceText` and translations inside the table

Switch language at runtime using:

```csharp
LocalizationService.CurrentLanguage = "fr";
```

All `LocalizedTMPKeyed` components refresh automatically through the centralized event pipeline.

<figure><img src="/files/1r1sPC4mYq5fG6g6KONc" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Workflow" %}
Smart Localization Suite operates on a strict key-based model.

Each text element references a key. The key resolves to a `LocalizationTable` entry containing:

* `sourceText`
* Translations per language
* Cached lookup for fast runtime access

Translation is performed exclusively through the table, never through scene components.

When translating:

1. The system reads `sourceText`
2. Determines target languages from runtime configuration
3. Applies quota validation
4. Sends requests via the selected provider
5. Writes results directly into the table
6. Rebuilds the table cache
7. Refreshes components automatically

Provider selection is centralized through a factory pattern, enabling interchangeable backend APIs without modifying runtime behavior.

Supported providers include:

* MyMemory
* Google Cloud
* Azure Translator
* Amazon Translate (SigV4)
* DeepL
* IBM Watson
* Yandex Cloud
* LibreTranslate
* Smartling

The Suite also includes automated migration tools capable of converting Lite projects into key-based table structures.

<figure><img src="/files/XvMPLoBQfZTobhS3MG5m" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Technical Notes" %}

### Key-Based Architecture

All runtime resolution is based on:

* `LocalizationService`
* `LocalizationTable`
* `LocalizedTMPKeyed`

No translation logic is embedded inside components. Components reference keys only.

The table maintains an internal cache for fast lookup and rebuilds when modified.

***

### Editor-Only Secret Management

All provider credentials are stored in `EditorLocalizationSettings`, which must reside under an `Editor/` folder.

During build, `BuildSecretGuard` scans `Resources/` folders and fails the build if potential secrets are detected.

This prevents accidental leakage of:

* API keys
* Bearer tokens
* AWS credentials
* Azure subscription keys
* DeepL keys

This safety layer is mandatory for professional deployment scenarios.

***

### Translation Engine

Translation is processed through `EditorTranslator.TranslateKeyAsync`.

Features include:

* Dry-run validation dialog
* Per-language translation control
* Missing-only mode
* Retry policy (3 attempts)
* Cancellation support
* Character consumption tracking
* Partial quota handling

For MyMemory, local daily quota enforcement is applied. For commercial providers, billing is delegated to the provider infrastructure.

***

### Migration & Automation

The Suite includes:

* `AutoSetupTool` — One-click environment bootstrap
* `AutoMigrationTool` — Table normalization and Lite conversion

The system ensures:

* A LocalizationTable always exists
* `sourceText` is backfilled if missing
* Scene components are refreshed
* Legacy structures are normalized

### Architecture

SmartLocalizationSuite uses a key-based architecture where all translatable strings are identified by a unique key stored in a `LocalizationTable` ScriptableObject. The runtime binding is handled by a single MonoBehaviour (`LocalizedTMPKeyed`) that resolves a key to a translated string at runtime via `LocalizationService`.

All Editor logic (translation, scanning, import/export, build hooks) lives in Editor-only assemblies and is never included in builds.

***

### Data model

* `LocalizationTable` (ScriptableObject) — list of `KeyEntry` objects, each holding a `key`, a `sourceText` and a list of `Translation` records (`languageCode` + `value`)
* `LocalizationSettings` (ScriptableObject, in Resources) — language list with `code` and `display` name per language; single source of truth at runtime
* `EditorLocalizationSettings` (ScriptableObject, Editor-only folder) — provider selection, API credentials, daily quota tracking and build validation mode

***

### Translation layer

All providers implement `ITranslationProvider` with a single `TranslateAsync(text, from, to, ct)` method. Provider selection and language code normalization are handled by `ProviderFactory` and `EditorTranslator`.

Notable normalization rules:

* DeepL requires uppercase codes (`EN`, `FR`, `PT-PT`, `PT-BR`)
* Azure prefers two-letter lowercase codes, regional variants are stripped
* All other providers use lowercase codes as-is

A `RetryPolicy` with 3 attempts wraps every provider call. Translation supports cancellation via `CancellationToken` and reports progress through `EditorUtility.DisplayProgressBar`.

#### Supported providers

| Provider                       | Notes                                               |
| ------------------------------ | --------------------------------------------------- |
| MyMemory                       | Free tier, daily character quota managed locally    |
| LibreTranslate                 | Self-hostable, configurable base URL                |
| Google Cloud Translate v2      | API key authentication                              |
| Azure Translator               | Subscription key + region                           |
| Amazon Translate               | SigV4 authentication (access key + secret + region) |
| DeepL                          | Free and Pro API, uppercase language codes          |
| IBM Watson Language Translator | Endpoint + API key + version date                   |
| Yandex Cloud Translate         | IAM token + folder ID                               |
| Smartling                      | Bearer token authentication                         |

***

### Dashboard & Editor windows

The main entry point is `SmartLocalizationDashboardFinal` (`Tools > Smart Localization Suite > Dashboard`), an `EditorWindow` with five tabs:

| Tab            | Purpose                                                                 |
| -------------- | ----------------------------------------------------------------------- |
| Setup          | Configure languages, provider and build validation mode                 |
| Table          | View, edit and translate all keys inline with pagination and search     |
| Scene          | Select and translate `LocalizedTMPKeyed` components in the active scene |
| Coverage       | Per-language translation coverage report                                |
| Data Integrity | Duplicate detection, safe rename and orphan scan                        |

***

### Coverage Scanner

`LocalizationCoverageScanner` scans all `LocalizationTable` assets in the project and produces a `GlobalCoverageReport` containing a `CoverageReport` per language.

Each `CoverageReport` exposes:

* `coveragePercent` — percentage of keys with a non-empty translation
* `translatedKeys` / `missingKeys` — exact counts
* `missingKeysList` — full list of missing key strings

The scanner is called both from the Coverage tab in the dashboard and from the build pipeline at build time.

***

### Build pipeline hooks

Two `IPreprocessBuildWithReport` hooks run automatically before every build:

**`BuildSecretGuard`** (order 0) Ensures `EditorLocalizationSettings` is not located inside a `Resources` folder. If it is, the build is aborted with a descriptive error. This prevents API credentials from being bundled in the player build.

**`LocalizationBuildValidator`** (order 100) Runs `LocalizationCoverageScanner.ScanAllTables()` and evaluates the result against the configured `ValidationMode`:

| Mode       | Behaviour                                                                        |
| ---------- | -------------------------------------------------------------------------------- |
| `Disabled` | No validation, build always proceeds                                             |
| `Warning`  | Missing translations are logged as warnings, build proceeds                      |
| `Strict`   | Build fails with `BuildFailedException` if any language has missing translations |

`ValidationMode` is set per-project in `EditorLocalizationSettings` and exposed in the Setup tab of the dashboard.

***

### Data Integrity tools

Three static utility classes are available under the Data Integrity tab.

#### Duplicate Detection — `DuplicateDetectionTool`

Scans all `LocalizationTable` assets for duplicate keys within the same table or across multiple tables. Returns a `ScanResult` listing each duplicate key, the tables it appears in and the number of occurrences. Duplicate entries can be removed in one click; the first occurrence is always kept.

#### Safe Rename — `SafeRenameTool`

Renames a key globally across:

* All `LocalizationTable` ScriptableObject assets
* All prefabs containing a `LocalizedTMPKeyed` component referencing that key
* All open scenes containing a `LocalizedTMPKeyed` component referencing that key

The operation is wrapped in `Undo.RecordObject` calls on every affected asset, making it fully undoable and redoable. Returns a `RenameReport` listing all modified asset paths.

#### Orphan Scan — `OrphanScanTool`

Produces an `OrphanReport` with two categories:

* **Unused keys** — keys defined in a `LocalizationTable` but not referenced by any `LocalizedTMPKeyed` component in prefabs or scenes
* **Missing references** — `LocalizedTMPKeyed` components whose assigned key does not exist in their assigned `LocalizationTable`

Unused keys can be removed directly from the scan result.

***

### CSV format

```
key;en;fr;de;es
ui.btn.start;Start;Démarrer;Starten;Iniciar
ui.menu.settings;Settings;Paramètres;Einstellungen;
```

* **Separator** — semicolon by default; comma is also accepted and auto-detected on import
* **Encoding** — UTF-8 with BOM on export; UTF-8 without BOM accepted on import
* **Source language column** — maps to `sourceText` internally; identified by the source language code (e.g. `en`), not by a literal `sourceText` header (legacy `sourceText` header still accepted for backwards compatibility)
* **Import validation** — headers are checked for duplicates, unknown language columns are rejected in strict mode, duplicate key rows abort the import
* **Delimiter-shift guard** — import detects CSVs where language columns contain values equal to the key (a common symptom of wrong delimiter or Excel re-export) and aborts with a descriptive error
* **Import Preview** — runs the full import logic without writing any data and returns a `created / updated / skipped / invalid` report for user confirmation before applying

#### JSON export

JSON export is available alongside CSV. Two modes are supported:

* **All languages in one file** — `{ "en": { "key": "value", ... }, "fr": { ... } }`
* **One file per language** — `translations_en.json`, `translations_fr.json`, etc.

***

### Assembly layout

| Assembly                         | Contents                                                                                                                                                                   |
| -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `SmartLocalizationSuite.Runtime` | `LocalizationTable`, `LocalizationSettings`, `LocalizationService`, `LocalizedTMPKeyed`, `LocalizedTMPKeyedEditor` (Inspector)                                             |
| `SmartLocalizationSuite.Editor`  | Dashboard, translation providers, IO (CSV/JSON), build hooks (`BuildSecretGuard`, `LocalizationBuildValidator`), Coverage Scanner, Data Integrity tools, settings provider |
| `SmartLocalizationLite.Runtime`  | Lite version runtime (companion package)                                                                                                                                   |
| `SmartLocalizationLite.Editor`   | Lite version editor (companion package)                                                                                                                                    |

***

### Requirements

* Unity 2021.3 LTS or later
* TextMeshPro (included with Unity since 2018.3)
* No additional packages required

<figure><img src="/files/pLGWCrecljX1XLIWmoOx" alt=""><figcaption></figcaption></figure>
{% endtab %}

{% tab title="Limitations" %}
Smart Localization Suite does not include:

* Pluralization rules
* ICU formatting
* Dynamic runtime remote fetch
* Addressables integration
* Built-in CSV import/export
* External database syncing

Translation performance depends on the chosen provider and network conditions.

Batch translation per key is sequential to respect provider rate limits.

The system is strictly designed around TextMeshPro.
{% endtab %}

{% tab title="FAQ" %}

<details>

<summary>What is the main difference from the Lite version?</summary>

The Suite uses centralized key-based tables instead of per-component language entries. This ensures reuse, consistency, and scalability.

</details>

<details>

<summary>Are API keys safe in builds?</summary>

Yes. Secrets are stored in Editor-only assets. A pre-build scan (`BuildSecretGuard`) prevents builds if credentials are detected inside runtime resources&#x20;

</details>

<details>

<summary>Can I migrate from Lite automatically?</summary>

Yes. The Suite detects Lite installations and migrates data into a centralized `LocalizationTable`&#x20;

</details>

<details>

<summary>Can I switch providers without rewriting data?</summary>

Yes. Provider selection is abstracted via `ProviderFactory`. Changing providers does not affect stored translation data&#x20;

</details>

<details>

<summary>Does the system cache translations?</summary>

Yes. The `LocalizationTable` rebuilds and caches lookups after modification.

</details>

<details>

<summary>What happens if quota is exceeded?</summary>

For MyMemory, local quota enforcement prevents over-consumption. For paid providers, billing rules apply according to their service terms

</details>
{% endtab %}
{% endtabs %}

***

{% content-ref url="/spaces/u6FKPRtV6vGPNteP2vic/pages/0XuiYbnTVJFkYbnBhtKu" %}
[Smart Localization Suite Changelog](/julestools-docs/changelog/readme-6.md)
{% endcontent-ref %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://julestools.gitbook.io/julestools-docs/documentation/tools/smart-localization-suite.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
