Managing Locales
What this covers
How to set up and manage locales at the tenant and store levels: adding, activating, deactivating, deleting locales, and key constraints you must know before going live.
Locale model
Each locale in DJUST is defined by:
| Field | Type | Description |
|---|---|---|
code | String | IETF language tag (ISO 639-1-ISO 3166-1), e.g. fr-FR, en-GB |
label | String | Human-readable name, e.g. "France", "United Kingdom" |
main | Boolean | Whether this is the default locale |
active | Boolean | Whether this locale is currently enabled on the platform |
A locale must be active before it can be set as main. Conversely, the main locale cannot be deactivated or deleted.
Tenant-level locales
Concept
Every tenant has a set of locales configured at initialization. These locales define the full language repertoire available across the entire platform. Store-level locales are always a subset of tenant locales.
Key constraint: the default locale is immutable
The tenant's main locale (default) is set at tenant creation and cannot be changed afterwards. Changing it would require a full environment reset and re-import of all data to ensure consistency.
How to manage
Tenant locales can be managed through:
- Back Office: General settings > Locales management
- Admin API: see endpoints below
| Operation | Endpoint | Permission required | Notes |
|---|---|---|---|
| Add locale | POST /v1/settings/locale | GENERAL_SETTING_CREATE | Locale code must follow IETF format |
| List locales | GET /v1/settings/locale | GENERAL_SETTING_READ | Supports ?active=true filter |
| Available pool | GET /v1/settings/locale/available | GENERAL_SETTING_READ | Returns all IETF locales not yet added |
| Get main locale | GET /v1/settings/locale/main | GENERAL_SETTING_READ | Returns the immutable default locale |
| Toggle active | PATCH /v1/settings/locale/{code} | GENERAL_SETTING_UPDATE | Cannot deactivate the main locale |
| Delete locale | DELETE /v1/settings/locale/{code} | GENERAL_SETTING_DELETE | Cannot delete the main locale |
Mirakl context
When the platform is connected to Mirakl, tenant locales are synchronized automatically via the Mirakl L01 API (platform languages). In this case:
- All active languages from Mirakl are imported with
active = true. - The
platform_defaultflag from Mirakl maps to themainfield. - Manual editing of locales in the Back Office is disabled to prevent desynchronization.
Store-level locales
Concept
In a multi-store setup, each store can define its own set of locales and its own default locale. Store locales must be chosen from the tenant's locale pool — you cannot add a locale to a store if it does not exist at the tenant level.
Each store has:
- Supported locales: the set of IETF tags available for that store.
- Default locale (
main = true): the store's primary locale, used for fallback and Back Office display.
How to manage
| Operation | Endpoint | Permission required | Notes |
|---|---|---|---|
| List store locales | GET /v1/stores/{storeId}/locales | STORE_READ | |
| Add to store | POST /v1/stores/{storeId}/locales | STORE_UPDATE | Code must exist in tenant locales |
| Update store locale | PUT /v1/stores/{storeId}/locales/{code} | STORE_UPDATE | Can toggle active/main |
| Remove from store | DELETE /v1/stores/{storeId}/locales/{localeId} | STORE_UPDATE | Cannot delete the store's main locale |
Validation rules
The platform enforces these constraints:
| Rule | Error code |
|---|---|
| Locale not available in tenant | ST00015 |
| Store cannot have multiple main locales | ST00016 |
| Locale not found | ST00017 |
| Cannot delete a locale that is main in any store | ST00018 |
| Cannot deactivate a locale that is main in any store | ST00019 |
| Cannot deactivate the store's main locale | ST00020 |
| Locale already linked to store | ST00021 |
| Inactive locale cannot be set as main | ST00022 |
For the full list of error and warning codes, see Error / Warning codes.
Fallback chain
When a localized label is missing for the requested locale, DJUST applies this deterministic chain:
flowchart LR
%% Styles (Readme)
classDef read fill:#ede9fe,stroke:#7c3aed,stroke-width:2px,color:#1e1b4b;
classDef decision fill:#fff4e5,stroke:#f59e0b,stroke-width:2px,color:#7a3e00;
classDef ok fill:#ecfdf5,stroke:#10b981,stroke-width:2px,color:#064e3b;
classDef stop fill:#fee2e2,stroke:#ef4444,stroke-width:2px,color:#7f1d1d;
A["📘 Client requests label<br>for locale e.g. en-GB"]:::read --> B{"Label exists<br>for requested locale?"}:::decision
B -->|Yes| C["✅ Return label"]:::ok
B -->|No| D{"Store default<br>locale configured?"}:::decision
D -->|Yes| E{"Label exists for<br>store default?"}:::decision
E -->|Yes| C
E -->|No| F{"Label exists for<br>tenant default?"}:::decision
D -->|No| F
F -->|Yes| C
F -->|No| G["Empty string"]:::stop
This fallback applies to labels only (names, descriptions, option display values). Canonical values (codes, keys, URLs) are never locale-dependent.
Impact on other features
| Feature | How locales affect it |
|---|---|
| Indexation | One search index is created per store x store-view x locale combination. Index naming pattern: {tenant}_{store}_{storeView}_{locale}. |
| Emails | Email templates are stored per locale. The customer user's locale determines which template is sent. |
| Imports | Localized columns use the fieldName[locale] pattern. Only active locales are accepted. |
| Back Office | Localized fields show dynamic language tabs matching the active locales. |
Updated 25 days ago
