Multi-language (i18n)

Struktural handles localization at two completely distinct levels: the Static UI definition and the Dynamic Database data.

Static UI Translation (System vs Domain)

The frontend interface relies on JSON dictionaries to translate button labels, menu items, and grid headers.

Defining Translations via Studio UI

In the Multilanguage module, you can view a grid of all translation keys across all available languages. To avoid manual data entry, use the "Sync & Clean Domain Keys" action (under the AI menu). This scans the schema, menus, and C# scripts for AddError() calls, extracts all necessary keys, and uses the AI integration to automatically translate them into all configured languages.

The JSON Structure

Translations use a flat key-value structure utilizing dot-notation. Do not nest JSON objects.

Example: i18n/es.domain.json

{
  "entities.Customer": "Cliente",
  "entities.Customer_plural": "Clientes",
  "Customer.Name": "Nombre del Cliente",
  "menu.Sales": "Ventas",
  "errors.Customer.InvalidTaxId": "El identificador fiscal no es vĂ¡lido."
}

Dynamic Data Translation (Multilanguage Fields)

If your application needs to store user-generated data in multiple languages (e.g., a Product Description), you configure the entity schema rather than the static dictionaries.

UI Approach: In the Data Schema editor, check the "Multilang" checkbox next to the field. JSON Approach: Add the field name to the Multilanguage array on the EntityDefinition.

{
  "Name": "Product",
  "Multilanguage": ["Description"],
  "Fields": [
    { "Name": "Description", "Type": "String" }
  ]
}

How it works under the hood: The engine extracts Description from the main Product table and generates a shadow table named Product_Translation. When a user requests data, the backend inspects the Accept-Language HTTP header (or the user's manual override) and dynamically executes a SQL LEFT JOIN to fetch the translation corresponding to the active Data Language.