Translations for developers
How translation files are organised, how to add a language and how admin overrides work.
How texts are stored#
| Where | Used for |
|---|---|
lang/en.json |
Short storefront strings used as __('Add to cart') (the English text is the key). |
lang/en/*.php |
Grouped strings: admin.php, admin_catalog.php, admin_sales.php, admin_settings.php, admin_settings_fields.php, admin_content.php, admin_ai.php, account.php, auth.php, install.php, emails.php, enums.php, api.php, core.php. |
| Database (translatable columns) | Content you edit in the admin: product names, descriptions, page text, menu labels, settings such as the tagline (spatie/laravel-translatable). |
| Database (translation overrides) | Edits made in System > Translations. |
Add a language#
- Settings > Languages > Add: code (for example
it), names and direction (ltrorrtl). Activate it. - Create the interface texts, either:
- in System > Translations, using copy from English then editing, or
- by files: copy
lang/en.jsontolang/it.jsonand eachlang/en/*.phptolang/it/*.php, then translate the values (never the keys and never the:placeholders). - For the setup wizard, copy only
lang/en/install.phptolang/it/install.php; the wizard's language picker lists every folder that contains aninstall.php. - Clear caches. The translation editor and
TranslationLoader::flush($locale)also refresh them.
Rules for translators: keep :name, {name}, %s placeholders and HTML tags exactly as they are, and keep plural forms ({1} ... |[2,*] ...).
Writing translatable code#
__('Add to cart'); // JSON key
__('admin_catalog.products.title'); // group key
trans_choice('admin_settings.system.pending', $count, ['count' => $count]);
In Blade use {{ __('...') }}. Any new string you add should exist in lang/en.json or the proper lang/en/*.php group so it shows up in the translation editor.
Translatable fields on models#
Models use TranslatesAttributes with spatie/laravel-translatable. The fallback is the default language (fallbackAny is on), so a missing translation shows the default text instead of an empty one. Seed data stores translatable settings as {"en": ...}.
RTL#
Direction comes from the language record. The layouts set dir="rtl", and each stylesheet has an .rtl.css twin generated by npm run build:rtl (see Theme presets and rebuilding CSS). The admin stylesheet uses logical properties and works in both directions. Prefer logical CSS (margin-inline-start, padding-inline) in new code.
Machine translation#
If the AI Studio is configured, the Translator tool can draft translations while protecting placeholders and HTML. Always have a native speaker review the result.